home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume10 / sh_dos / part02 < prev    next >
Encoding:
Text File  |  1990-02-13  |  79.3 KB  |  2,455 lines

  1. Newsgroups: comp.sources.misc
  2. organization: ITM Sector, Data Logic Ltd. (A Raytheon Company)
  3. From: istewart@datlog.co.uk (Ian Stewartson)
  4. subject: v10i054: MSDOS Shell (sh) Implementation - Part 01 of 05
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 10, Issue 54
  8. Submitted-by: istewart@datlog.co.uk (Ian Stewartson)
  9. Archive-name: sh_dos/part02
  10.  
  11. #!/bin/sh
  12. # shar:    Shell Archiver  (v1.23)
  13. #
  14. # This is a shell archive, meaning:
  15. # 1. Remove everything above the #! /bin/sh line.
  16. # 2. Save the resulting text in a file.
  17. # 3. Execute the file with /bin/sh (not csh) to create the files.
  18. #
  19. #
  20. # This is part 1 of a multipart archive                                    
  21. # do not concatenate these parts, unpack them in order with /bin/sh        
  22. #
  23. #    The following text will create:
  24. #      Install
  25. #      MANIFEST
  26. #      Notes
  27. #      ReadMe
  28. #      sh.1
  29. #      include/Changes
  30. #      include/sys/dirent.h
  31. #      include/sys/proto.h
  32. #      include/dirent.h
  33. #      include/unistd.h
  34. #      include/ms_dio.h
  35. #      lib/ms_dio.c
  36. #      lib/director.c
  37. #      lib/popen.c
  38. #      lib/syserr.c
  39. #      lib/stdargv.c
  40. #      lib/pnmatch.c
  41. #      lib/getopt.c
  42. #      scripts/l
  43. #      scripts/extend.lst
  44. #      scripts/profile.sh
  45. #      shell/Makefile
  46. #      shell/sh1.c
  47. #      shell/sh2.c
  48. #      shell/sh3.c
  49. #      shell/sh4.c
  50. #      shell/sh5.c
  51. #      shell/sh6.c
  52. #      shell/sh7.c
  53. #      shell/sh8.c
  54. #      shell/sh9.c
  55. #      shell/sh10.c
  56. #      shell/sh0.asm
  57. #      shell/sh.h
  58. #
  59. if test -r s2_seq_.tmp
  60. then echo "Must unpack archives in sequence!"
  61.      next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
  62.      exit 1; fi
  63. for i in include include/sys lib scripts shell
  64. do
  65. echo "x - creating directory $i"
  66. mkdir $i
  67. done
  68. echo "x - extracting Install (Text)"
  69. sed 's/^X//' << 'SHAR_EOF' > Install &&
  70. X MS-DOS Shell Version 1.4    INSTALL                January 1990
  71. X
  72. X MS-DOS SHELL - Copyright (c) 1990 Data Logic Limited and Charles Forsyth
  73. X
  74. X This code is based on (in part) the shell program written by Charles
  75. X Forsyth and is subject to the following copyright restrictions:
  76. X
  77. X 1.  Redistribution and use in source and binary forms are permitted
  78. X     provided that the above copyright notice is duplicated in the
  79. X     source form and the copyright notice in file sh6.c is displayed
  80. X     on entry to the program.
  81. X
  82. X 2.  The sources (or parts thereof) or objects generated from the
  83. X     sources (or parts of sources) cannot be sold under any circumstances.
  84. X
  85. X    $Header: install 1.1 90/01/29 18:03:04 MS_user Exp $
  86. X
  87. X    $Log:    install $
  88. X# Revision 1.1  90/01/29  18:03:04  MS_user
  89. X# Initial revision
  90. X# 
  91. X________________________________________________________________________________
  92. X
  93. XTo rebuild and install the shell, you should follow the following the
  94. Xsteps:
  95. X
  96. X1)  Load the include files in the include directory into the standard
  97. X    location (\msc\include or equivalent).  Read CHANGES file for the
  98. X    additional definitions which are required in the standard Microsoft
  99. X    5 include files and edit them in to the appropriate files.
  100. X
  101. X    We have standardised our MSDOS and Unix include files such that
  102. X    the same include file exists our Unix system and MSDOS systems.
  103. X    This makes porting a lot easier.  If you don't want to edit the
  104. X    standard include files, you will have to generate an new include
  105. X    file for the shell and include it as the first include in all the
  106. X    C sources for the additional library functions and the Shell itself
  107. X
  108. X2)  Modify the library function open so that the O_NOINHERIT flag is
  109. X    passed to MSDOS by the library.  This is not strictly necessary.
  110. X    I did it using CodeView to see where the library function masks
  111. X    the bottom three bits, noted the bytes around this location,
  112. X    extracted the open function from the library, patched the mask
  113. X    to be 0x83 instead of 0x03, and then replaced the function in the
  114. X    library.
  115. X
  116. X3)  Compile the library files in the directory /lib in large model mode
  117. X    and add the objects to your large model library
  118. X
  119. X    cl -c -AL -Olt *.c
  120. X    <appropriate library commands>
  121. X
  122. X4)  Build the shell, either using make or
  123. X
  124. X    cl -c -AL -Olt *.c
  125. X    masm /Ml sh0.asm
  126. X    link sh0+sh1+sh2+sh3+sh4+sh5+sh6+sh7+sh8+sh9+sh10/noi, sh.exe;
  127. X
  128. X    Note that the order is important.  SH0.OBJ must be the first object
  129. X    file in the load line.
  130. X
  131. X    Install the shell in its correct location.
  132. X
  133. X5)  Modify the scripts as appropriate for your installation and install
  134. X    them in the correct directories.
  135. X
  136. X6)  Type "sh -0" and see what happens.
  137. SHAR_EOF
  138. chmod 0644 Install || echo "restore of Install fails"
  139. set `wc -c Install`;Sum=$1
  140. if test "$Sum" != "2694"
  141. then echo original size 2694, current size $Sum;fi
  142. echo "x - extracting MANIFEST (Text)"
  143. sed 's/^X//' << 'SHAR_EOF' > MANIFEST &&
  144. XInstall            | Installation instructions
  145. XMANIFEST        | This list
  146. XNotes            | Some addition notes
  147. XReadMe            | The Release Readme
  148. Xsh.1            | The Manual page in *roff format
  149. Xinclude/Changes        | Changes to standard include files
  150. Xinclude/dirent.h    | Directory (3) functions include
  151. Xinclude/unistd.h    | unistd for MSDOS
  152. Xinclude/ms_dio.h    | MSDOS raw disk/memory I/O include file
  153. Xinclude/sys/dirent.h    | Second part of directory (3) functions include file
  154. Xinclude/sys/proto.h    | Prototype definitions
  155. Xlib/ms_dio.c        | MSDOS raw disk/memory I/O functions
  156. Xlib/director.c        | POSIX directory (3) functions for MSDOS
  157. Xlib/popen.c        | popen/pclose for MSDOS
  158. Xlib/syserr.c        | Modified sys_errlist for MSDOS
  159. Xlib/stdargv.c        | Replacement command list processing for programes
  160. Xlib/pnmatch.c        | Pattern matching function
  161. Xlib/getopt.c        | getopt function
  162. Xscripts/l        | A sample shell script
  163. Xscripts/extend.lst    | A sample extended command line processing list
  164. Xscripts/profile.sh    | A sample start up shell script
  165. Xshell/Makefile        | Shell - makefile 
  166. Xshell/sh0.asm        | Shell - Swap functions
  167. Xshell/sh1.c        | Shell - Main program and memory control functions
  168. Xshell/sh2.c        | Shell - Parser functions
  169. Xshell/sh3.c        | Shell - Parse tree processing functions
  170. Xshell/sh4.c        | Shell - Word processing functions
  171. Xshell/sh5.c        | Shell - Filename expansion functions
  172. Xshell/sh6.c        | Shell - Global variables
  173. Xshell/sh7.c        | Shell - Built-in functions
  174. Xshell/sh8.c        | Shell - Unix I/O Emulation
  175. Xshell/sh9.c        | Shell - History processing functions
  176. Xshell/sh10.c        | Shell - Function print/save/delete functions
  177. Xshell/sh.h        | Shell - Header file
  178. SHAR_EOF
  179. chmod 0644 MANIFEST || echo "restore of MANIFEST fails"
  180. set `wc -c MANIFEST`;Sum=$1
  181. if test "$Sum" != "1578"
  182. then echo original size 1578, current size $Sum;fi
  183. echo "x - extracting Notes (Text)"
  184. sed 's/^X//' << 'SHAR_EOF' > Notes &&
  185. XThe following addition points are noted about the Shell.
  186. X
  187. X1)  EMS 3.2 or above is required if expanded memory is to be used.
  188. X
  189. X2)  It has been tested on MS-DOS 3.3 and 4.0 and under OS/2 in the
  190. X    DOS box.
  191. X
  192. X3)  Not all the addition library functions are required.  Some are
  193. X    just included for your interest.  Their functionality is
  194. X    briefly described below:
  195. X
  196. X    director.c (required)
  197. X
  198. X    MSDOS versions of the POSIX directory (3) functions (see
  199. X    POSIX standards and Unix manual pages for further information).
  200. X
  201. X    getopt.c (required)
  202. X
  203. X    The getopt function
  204. X
  205. X    stdargv.c (required)
  206. X
  207. X    A replacement for the standard Microsoft library stdargv.obj.
  208. X    This function tries to provide the wildcard expansion functionality
  209. X    normally provided by Unix.  *, ?, [] and \ are supported.
  210. X    Environment variables are expanded and the selection of files
  211. X    across wildcard drive letters is supported (ie *:*.c will
  212. X    expand to all the .c files in the current directory of all
  213. X    drives).
  214. X
  215. X    pnmatch.c (required)
  216. X
  217. X    A pattern match function used by stdargv
  218. X
  219. X    ms_dio.c
  220. X
  221. X    A set of functions to allow you to do raw disk and memory
  222. X    I/O.  The include file ms_dio has a set of macros to
  223. X    change the normal library calls so that they go via this
  224. X    package.
  225. X
  226. X    popen.c
  227. X
  228. X    A version of popen for MS-DOS
  229. X
  230. X    syserr.c
  231. X
  232. X    A modified version of the standard Microsoft error list.
  233. SHAR_EOF
  234. chmod 0644 Notes || echo "restore of Notes fails"
  235. set `wc -c Notes`;Sum=$1
  236. if test "$Sum" != "1334"
  237. then echo original size 1334, current size $Sum;fi
  238. echo "x - extracting ReadMe (Text)"
  239. sed 's/^X//' << 'SHAR_EOF' > ReadMe &&
  240. X MS-DOS Shell Version 1.4    README                January 1990
  241. X
  242. X MS-DOS SHELL - Copyright (c) 1990 Data Logic Limited and Charles Forsyth
  243. X
  244. X This code is based on (in part) the shell program written by Charles
  245. X Forsyth and is subject to the following copyright restrictions:
  246. X
  247. X 1.  Redistribution and use in source and binary forms are permitted
  248. X     provided that the above copyright notice is duplicated in the
  249. X     source form and the copyright notice in file sh6.c is displayed
  250. X     on entry to the program.
  251. X
  252. X 2.  The sources (or parts thereof) or objects generated from the
  253. X     sources (or parts of sources) cannot be sold under any circumstances.
  254. X
  255. X    $Header: readme 1.1 90/01/25 13:43:20 MS_user Exp $
  256. X
  257. X    $Log:    readme $
  258. X# Revision 1.1  90/01/25  13:43:20  MS_user
  259. X# Initial revision
  260. X# 
  261. X________________________________________________________________________________
  262. X
  263. XThis is an implementation of the Unix Shell for MSDOS.  As far as
  264. Xpossible it is compatible with the System V.3 program sh(1).  The
  265. Xfollowing differences are noted:
  266. X
  267. X1)  Background or asynchronous commands are not supported
  268. X
  269. X2)  Certain internal commands which have no equivalent MSDOS supported
  270. X    functionality support (ulimit, time etc) are not provided.
  271. X
  272. X3)  Command hashing and accounting are not supported.
  273. X
  274. X4)  The Shell uses all variables starting with a ~ (tilde) internally
  275. X    and will not allow you to display them.  I don't think this is a
  276. X    difference from the user's view, just internally.
  277. X
  278. X5)  8 bit character sets are not supported.
  279. X
  280. XThe following enhancements have been made for the MSDOS environment.
  281. XThese enhancements are described in the appropriate section of the
  282. Xmanual pages.
  283. X
  284. X1)  The Shell will swap itself out to one of the following:
  285. X
  286. X    - Expanded memory
  287. X    - Extended memory
  288. X    - Disk (this is the slowest)
  289. X
  290. X    The swapping is controlled by the shell internal command swap.  If
  291. X    swapping is enabled, the shell only uses 3K of memory whilst a
  292. X    child process is executing.
  293. X
  294. X    Note: Swapping to Extended memory is probably the most dangerous
  295. X      because there is no memory manager available for it.
  296. X
  297. X2)  History processing has been added.
  298. X
  299. X3)  Command line editing has been added.
  300. X
  301. X4)  The command line prompt can be programmed to display 'useful'
  302. X    information.
  303. X
  304. X5)  The shell uses Unix format file names (ie slashes and not
  305. X    backslashes) to delimit directories.  Some programs require certain
  306. X    environment variables to be in MS-DOS format (using backslashes).
  307. X    The msdos command allows these variables to be marked so that they
  308. X    are set correctly when the environment for a program is set up.
  309. X
  310. X6)  Extended command line processing is supported using the parameter
  311. X    @<filename> to a command.  Examples of this include the Microsoft
  312. X    Linker and Librarian and of course the Shell itself.  A version of
  313. X    stdargv.c which supports this format (and wildcards from a normal
  314. X    command line) is included.
  315. X
  316. X7)  Wild cards on drives (ie echo *:*.c will echo all the C files in 
  317. X    the current directories of each drive) are supported.
  318. X
  319. XIn order to rebuild this program, you need the DIRECTORY(3) functions
  320. Xfor MSDOS (also included) and the version of open in your library must
  321. Xpass the O_NOINHERIT bit on the MSDOS kernel.  The Microsoft C V5.1
  322. Xlibrary does not pass this bit on to the MSDOS open System call.  I
  323. Xfixed this using CodeView to find where the library function masks off
  324. Xthe bottom 2 bits.  Extracted the object from the library and patched
  325. Xmask from 0x03 to 0x83 in the object and reload into the library.  No
  326. XProblem.
  327. X
  328. XYou can do want you like with this software as long as you don't sell
  329. Xit or remove the Copyright notices in the sources or object.
  330. X
  331. XIf you have any problems or want to let me know about any enhancements
  332. Xyou have made (which could be included in a new general release), you
  333. Xcan contact me at
  334. X
  335. X    Data Logic Limited
  336. X    Queens House
  337. X    Greenhill Way
  338. X    Harrow
  339. X    Middlesex, HA1 1YR
  340. X    UK.
  341. X
  342. X    Phone : +44 1 863 0383
  343. X    E-Mail: istewart@datlog.co.uk or ukc!datlog!istewart
  344. X
  345. XNote:
  346. X    Unix is a registered trademark of AT&T Bell Laboratories
  347. X    Microsoft, MSDOS and CodeView are registered trademarks of Microsoft
  348. X    Corporation
  349. SHAR_EOF
  350. chmod 0644 ReadMe || echo "restore of ReadMe fails"
  351. set `wc -c ReadMe`;Sum=$1
  352. if test "$Sum" != "4188"
  353. then echo original size 4188, current size $Sum;fi
  354. echo "x - extracting sh.1 (Text)"
  355. sed 's/^X//' << 'SHAR_EOF' > sh.1 &&
  356. X.\"
  357. X.\" MS-DOS SHELL - Manual Page
  358. X.\"
  359. X.\" MS-DOS SHELL - Copyright (c) 1990 Data Logic Limited
  360. X.\"
  361. X.\" This code is subject to the following copyright restrictions:
  362. X.\"
  363. X.\" 1.  Redistribution and use in source and binary forms are permitted
  364. X.\"     provided that the above copyright notice is duplicated in the
  365. X.\"     source form and the copyright notice in file sh6.c is displayed
  366. X.\"     on entry to the program.
  367. X.\"
  368. X.\" 2.  The sources (or parts thereof) or objects generated from the sources
  369. X.\"     (or parts of sources) cannot be sold under any circumstances.
  370. X.\"
  371. X.\"    $Header: sh.1 1.1 90/01/24 14:17:00 MS_user Locked $
  372. X.\"
  373. X.\"    $Log:    sh.1 $
  374. X.\"    Revision 1.1  90/01/24  14:17:00  MS_user
  375. X.\"    Initial revision
  376. X.\"    
  377. X.\"
  378. X.\"
  379. X.ds OK [\|
  380. X.ds CK \|]
  381. X.TH SH 1L "Data Logic Limited" "MS-DOS Version 1.4"
  382. X.SH NAME
  383. Xsh, rsh - shell, the standard/restricted command programming language
  384. X.SH SYNOPSIS
  385. X\fBsh\fR [ \fB-acefhiknmrstuvx\fR ] [ args ]
  386. X.br
  387. X\fBrsh\fR [ \fB-acefhiknmrstuvx\fR ] [ args ]
  388. X.SH DESCRIPTION
  389. X\fISh\fR is a command programming language that executes commands read from a
  390. Xterminal or a file.  \fIRsh\fR is a restricted version of the standard command
  391. Xinterpreter \fIsh\fR; it is used to set up login names and execution
  392. Xenvironments whose capabilities are more controlled than those of the standard
  393. Xshell.  See \fIInvocation\fR below for the meaning of arguments to the shell.
  394. X.SS Definitions
  395. XA \fIblank\fR is a tab or a space.  A \fIname\fR is a sequence of letters,
  396. Xdigits, or underscores beginning with a letter or underscore.  A \fIparameter\fR
  397. Xis a name, a digit, or any of the characters \fB*\fR, \fB@\fR, \fB#\fR, \fB?\fR,
  398. X\fB-\fR, \fB$\fR, and \fB!\fR.
  399. X.SS Commands
  400. XA \fIsimple-command\fR is a sequence of non-blank \fIwords\fR separated by
  401. X\fIblanks\fR.  The first word specifies the name of the command to be executed.
  402. XExcept as specified below, the remaining words are passed as arguments to the
  403. Xinvoked command.  The command name is passed as argument 0 (see \fIexec\fR(2)).
  404. XThe \fIvalue\fR of a simple-command is its exit status if it terminates
  405. Xnormally, or (octal) 200+\fIstatus\fR if it terminates abnormally (see
  406. X\fIsignal\fR(2) for a list of status values).
  407. X.PP
  408. XA \fIpipeline\fR is a sequence of one or more \fIcommands\fR separated by
  409. X\fB\(bv\fR (or, for historical compatibility, by \fB^\fR).
  410. XThe standard output of each command but the last is connected by a \fIpipe\fR(2)
  411. Xto the standard input of the next command.  Each command is run as a separate
  412. Xprocess; the shell waits for the last command to terminate.  The exit status
  413. Xof a pipeline is the exit status of the last command.
  414. X.PP
  415. XA \fIlist\fR is a sequence of one or more pipelines separated by \fB;\fR,
  416. X\fB&&\fR, or \fB\(bv\(bv\fR, and optionally terminated by \fB;\fR.  Of these
  417. Xthree symbols, \fB;\fR has a lower precedence than that of \fB&&\fR and
  418. X\fB\(bv\(bv\fR.  The symbols \fB&&\fR and \fB\(bv\(bv\fR also have equal
  419. Xprecedence.  A semicolon (\fB;\fR) causes sequential execution of the
  420. Xpreceding pipeline.  The symbol \fB&&\fR (\fB\(bv\(bv\fR) causes the
  421. X\fIlist\fR following it to be executed only if the preceding pipeline returns
  422. Xa zero (non-zero) exit status.  An arbitrary number of new-lines may appear in a
  423. X\fIlist\fR, instead of semicolons, to delimit commands.
  424. X.PP
  425. XA \fIcommand\fR is either a simple-command or one of the following.  Unless
  426. Xotherwise stated, the value returned by a command is that of the last
  427. Xsimple-command executed in the command.
  428. X.PP
  429. X.PD 0
  430. X.TP
  431. X\fBfor \fIname\fR \*(OK \fBin \fIword\fR ... \*(CK \fBdo \fIlist \fBdone\fR
  432. XEach time a \fBfor\fR command is executed, \fIname\fR is set to the next
  433. X\fIword\fR taken from the \fBin\fR \fIword\fR list.  If \fBin\fI word\fR ...
  434. Xis omitted, then the \fBfor\fR command executes the \fBdo\fR
  435. X\fIlist\fR once for each positional parameter that is set (see \fIParameter
  436. XSubstitution\fR below).  Execution ends when there are no more words in the
  437. Xlist.
  438. X.TP
  439. X\fBcase \fIword \fBin\fR \*(OK \fIpattern\fR \*(OK \(br \
  440. X\fIpattern\fR \*(CK ... \fB) \fIlist \fB;;\fR \*(CK ... \fBesac\fR
  441. XA \fBcase\fR command executes the \fIlist\fR associated with the first
  442. X\fIpattern\fR that matches \fIword\fR.  The form of the patterns is the same
  443. Xas that used for file-name generation (see \fIFile Name Generation\fR) except
  444. Xthat a slash, a leading dot, or a dot immediately following a slash need not
  445. Xbe matched explicitly, and the match is case sensitive. 
  446. X.TP
  447. X\fBif \fIlist \fBthen \fIlist\fR \*(OK \fBelif \fIlist \fBthen \fIlist\fR \*(CK ... \*(OK \fBelse \fIlist\fR \*(CK \fBf\&i\fR
  448. XThe \fIlist\fR following \fBif\fR is executed and, if it returns a zero exit
  449. Xstatus, the \fIlist\fR following the first \fBthen\fR is executed.  Otherwise,
  450. Xthe \fIlist\fR following \fBelif\fR is executed and, if its value is zero, the
  451. X\fIlist\fR following the next \fBthen\fR is executed.  Failing that, the
  452. X\fBelse \fIlist\fR is executed.  If no \fBelse \fIlist\fR or \fBthen \fIlist\fR
  453. Xis executed, then the \fBif\fR command returns a zero exit status.
  454. X.TP
  455. X\fBwhile \fIlist \fBdo \fIlist \fBdone\fR
  456. XA \fBwhile\fR command repeatedly executes the \fBwhile \fIlist\fR and, if
  457. Xthe exit status of the last command in the list is zero, executes the
  458. X\fBdo \fIlist\fR; otherwise the loop terminates.  If no commands in the
  459. X\fBdo \fIlist\fR are executed, then the \fBwhile\fR command returns a zero
  460. Xexit status; \fBuntil\fR may be used in place of \fBwhile\fR to negate the
  461. Xloop termination test.
  462. X.TP
  463. X\fB(\fIlist\fB)\fR
  464. X.br
  465. XExecute \fIlist\fR in a sub-shell.  The shell creates a new environment in
  466. Xwhich to execute the \fIlist\fR, but does not fork a sub-shell as a Unix
  467. Xsystem would.  The original environment is restored on completion.
  468. X.TP
  469. X\fB{\fIlist\fB;}\fR
  470. X.br
  471. X\fIlist\fR is simply executed.
  472. X.TP
  473. X\fIname \fB() {\fIlist\fB;}\fR
  474. XDefine a function which is referenced by \fIname\fR.  The body of the function
  475. Xis the \fIlist\fR of commands between \fB{\fR and \fB}\fR.  Execution of
  476. Xfunctions is described below (see \fIExecution\fR).
  477. X.PD
  478. X.PP
  479. XThe following words are only recognized as the first word of a command and
  480. Xwhen not quoted:
  481. X.if t .RS
  482. X.PP
  483. X.B
  484. X.if n if then else elif fi case esac for while until do done { }
  485. X.if t if  then  else  elif  f\&i  case  esac  for  while  until  do  done  {  }
  486. X.if t .RE
  487. X.SS Comments
  488. XA word beginning with \fB#\fR causes that word and all the following
  489. Xcharacters up to a new-line to be ignored.
  490. X.SS Command Substitution
  491. XThe standard output from a command enclosed in a pair of grave accents
  492. X(\fB\(ga\(ga\fR) may be used as part or all of a word; trailing new-lines
  493. Xare removed.
  494. X.SS Parameter Substitution
  495. XThe character \fB$\fR is used to introduce substitutable \fIparameters\fR.
  496. XThere are two types of parameters, positional and keyword.  If \fIparameter\fR
  497. Xis a digit, it is a positional parameter.  Positional parameters may be
  498. Xassigned values by \fBset\fR.  Keyword parameters (also known as variables)
  499. Xmay be assigned values by writing:
  500. X.RS
  501. X.PP
  502. X\fIname \(eq value\fR \*(OK \fIname \(eq value\fR \*(CK ...
  503. X.RE
  504. X.PP
  505. XPattern-matching is not performed on \fIvalue\fR.  There cannot be a function
  506. Xand a variable with the same \fIname\fR.
  507. X.PP
  508. X.PD 0
  509. X.TP
  510. X\fB${\fIparameter\fB}\fR
  511. XThe value, if any, of the parameter is substituted.  The braces are required
  512. Xonly when \fIparameter\fR is followed by a letter, digit, or underscore that
  513. Xis not to be interpreted as part of its name.  If \fIparameter\fR is
  514. X\fB*\fR or \fB@\fR, all the positional parameters, starting with \fB$1\fR,
  515. Xare substituted (separated by spaces).  Parameter \fB$0\fR is set from argument
  516. Xzero when the shell is invoked.
  517. X.TP
  518. X\fB${\fIparameter\fB:-\fIword\fB}\fR
  519. XIf \fIparameter\fR is set and is non-null, substitute its value; otherwise
  520. Xsubstitute \fIword\fR.
  521. X.TP
  522. X\fB${\fIparameter\fB:\(eq\fIword\fB}\fR
  523. XIf \fIparameter\fR is not set or is null set it to \fIword\fR; the value of
  524. Xthe parameter is substituted.  Positional parameters may not be assigned to
  525. Xin this way.
  526. X.TP
  527. X\fB${\fIparameter\fB:?\fIword\fB}\fR
  528. XIf \fIparameter\fR is set and is non-null, substitute its value; otherwise,
  529. Xprint \fIword\fR and exit from the shell.  If \fIword\fR is omitted, the
  530. Xmessage \(ga\(gaparameter null or not set\(aa\(aa is printed.
  531. X.TP
  532. X\fB${\fIparameter\fB:+\fIword\fB}\fR
  533. XIf \fIparameter\fR is set and is non-null, substitute \fIword\fR; otherwise
  534. Xsubstitute nothing.
  535. X.PD
  536. X.PP
  537. XIn the above, \fIword\fR is not evaluated unless it is to be used as the
  538. Xsubstituted string, so that, in the following example, \fBpwd\fR is executed
  539. Xonly if \fBd\fR is not set or is null:
  540. X.RS
  541. X.PP
  542. Xecho ${d:-\(gapwd\(ga}
  543. X.RE
  544. X.PP
  545. XIf the colon (\fB:\fR) is omitted from the above expressions, the shell only
  546. Xchecks whether \fIparameter\fR is set or not (\fIIt is not clear what this
  547. Xmeans\fR).
  548. X.PP
  549. XThe following parameters are automatically set by the shell:
  550. X.RS
  551. X.PD 0
  552. X.TP
  553. X.B #
  554. XThe number of positional parameters in decimal.
  555. X.TP
  556. X.B \-
  557. XFlags supplied to the shell on invocation or by the \fBset\fR command.
  558. X.TP
  559. X.B ?
  560. XThe decimal value returned by the last synchronously executed command.
  561. X.TP
  562. X.B $
  563. XThe process number of this shell.
  564. X.TP
  565. X.B !
  566. XThe process number of the last background command invoked.
  567. X.TP
  568. X.B ~
  569. XThe shell reserves all variables beginning with a \fB~\fR for its own
  570. Xinternal use and these variables cannot be accessed by the user.
  571. X.PD
  572. X.RE
  573. X.PP
  574. XThe following parameters are used by the shell:
  575. X.RS
  576. X.PD 0
  577. X.TP
  578. X.B
  579. X.SM CDPATH
  580. XThe search path for the \fIcd\fR command.  (Note that becuase a colon is used
  581. Xby MSDOS to indicate a drive, a semi-colon is used to separate the path names
  582. Xinstead of a colon - this implies that the CDPATH variable must be set using
  583. Xsingle or double quotes to surround the value).
  584. X.TP
  585. X.B
  586. X.SM EXTENDED_LINE
  587. XThis parameter defines a file containing a list of command which can accept
  588. Xan Extended Command Line using the indirect command file character \fB@\fR.
  589. XWhen a command which can process the Extended Command Line finds a parameter
  590. Xstarting with a \fB@\fR in the command list, treats the rest of the parameter
  591. Xas a file and reads the parameters from that file.  Examples of this
  592. Xfunctionality include the Standard \fBLinker\fR and \fBLibrarian\fR.  The
  593. Xfilename defined by \fBEXTENDED_LINE\fR contains a list of command (including
  594. Xthe .exe or .com extension) separated by a newlines.   If the command is in
  595. Xupper case, the file name on the command line is set up with backslashes as
  596. Xthe directory separator.  Otherwise, slashes (Unix style) are used.  This
  597. Xfunctionality allows the user to get round the 127 byte command line length
  598. Xlimit of MSDOS.
  599. X.TP
  600. X.B
  601. X.SM HISTFILE
  602. XThe file where command history is saved across login sessions.  The default
  603. Xvalue is \fB\s-1$HOME\s+1/history.sh\fR.
  604. X.TP
  605. X.B
  606. X.SM HOME
  607. XThe default argument (home directory) for the \fIcd\fR command.
  608. X.TP
  609. X.B
  610. X.SM IFS
  611. XInternal field separators, normally \fBspace\fR, \fBtab\fR, and \fBnew-line\fR.
  612. X.TP
  613. X.B
  614. X.SM MAIL
  615. XIf this parameter is set to the name of a mail file \fIand\fR the
  616. X\fB\s-1MAILPATH\s+1\fR parameter is not set, the shell informs the user of
  617. Xthe arrival of mail in the specified file.
  618. X.TP
  619. X.B
  620. X.SM MAILCHECK
  621. XThis parameter specifies how often (in seconds) the shell will check for the
  622. Xarrival of mail in the files specified by the \fB\s-1MAILPATH\s+1\fR or
  623. X\fB\s-1MAIL\s+1\fR parameters.  If set to 0, the shell will check before each
  624. Xprompt.
  625. X.TP
  626. X.B
  627. X.SM MAILPATH
  628. XA colon (\fB:\fR) separated list of file names.  If this parameter is set,
  629. Xthe shell informs the user of the arrival of mail in any of the specified
  630. Xfiles. Each file name can be followed by \fB%\fR and a message that will be
  631. Xprinted when the modification time changes.  The default message is
  632. X\fI"you have mail"\fR.
  633. X.TP
  634. X.B
  635. X.SM PATH
  636. XThe search path for commands (see \fIExecution\fR below).  The user may not
  637. Xchange \fB\s-1PATH\s+1\fR if executing under \fIrsh\fR.  (Note that because a
  638. Xcolon is used by MSDOS to indicate a drive, a semi-colon is used to separate
  639. Xthe path names instead of a colon - this implies that the PATH variable must
  640. Xbe set using single or double quotes to surround the value).
  641. X.TP
  642. X.B
  643. X.SM PS1
  644. XPrimary prompt string, by default \(ga\(ga\fB$ \fR\(aa\(aa.  
  645. X.TP
  646. X.B
  647. X.SM PS2
  648. XSecondary prompt string, by default \(ga\(ga\fB> \fR\(aa\(aa. 
  649. X.TP
  650. X.B
  651. X.SM SHELL
  652. XWhen the shell is invoked, it scans the environment (see \fIEnvironment\fR
  653. Xbelow) for this name.  If it is found and there is an 'r' in the file name
  654. Xpart of its value, the shell becomes a restricted shell.
  655. X.TP
  656. X.B
  657. X.SM TMP
  658. XThe location of temporary files created by the shell.
  659. X.RE
  660. X.PP
  661. XThe shell gives default values to \fB\s-1PATH\s+1\fR, \fB\s-1PS1\s+1\fR,
  662. X\fB\s-1PS2\s+1\fR, \fB\s-1SHELL\s+1\fR, \fB\s-1HOME\s+1\fR and
  663. X\fB\s-1IFS\s+1\fR.
  664. X.SS Blank Interpretation
  665. XAfter parameter and command substitution, the results of substitution are
  666. Xscanned for internal field separator characters (those found in
  667. X\fB\s-1IFS\s+1\fR) and split into distinct arguments where such characters
  668. Xare found.  Explicit null arguments (\fB""\fR or \fB\(aa\(aa\fR) are retained.
  669. XImplicit null arguments (those resulting from \fIparameters\fR that have no
  670. Xvalues) are removed.
  671. X.SS File Name Generation
  672. XFollowing substitution, each command \fIword\fR is scanned for the characters
  673. X\fB*\fR, \fB?\fR and \fB\*(OK\fR.  If one of these characters appears the word
  674. Xis regarded as a \fIpattern\fR.  The word is replaced with alphabetically
  675. Xsorted file names that match the pattern.  If no file name is found that
  676. Xmatches the pattern, the word is left unchanged.  The character \fB.\fR at the
  677. Xstart of a file name or immediately following a \fB/\fR, as well as the
  678. Xcharacter \fB/\fR itself, must be matched explicitly.  When matching
  679. Xpatterns for file names, the shell ignores the case of the pattern and the
  680. Xfile directory entries.  Generated file names are always in lower case.
  681. X.PP
  682. X.PD 0
  683. X.RS
  684. X.TP
  685. X\fB*\fR
  686. XMatches any string, including the null string.
  687. X.TP
  688. X\fB?\fR
  689. XMatches any single character.
  690. X.TP
  691. X\fB\*(OK ... \*(CK\fR
  692. XMatches any one of the enclosed characters.  A pair of characters separated by
  693. X\fB-\fR matches any character lexically between the pair, inclusive.  If the
  694. Xfirst character following the opening \(ga\(ga\*(OK\(aa\(aa is a
  695. X\fB\(ga\(ga!\(aa\(aa\fR any character not enclosed is matched.
  696. X.PD
  697. X.RE
  698. X.SS Quoting
  699. XThe following characters have a special meaning to the shell and cause
  700. Xtermination of a word unless quoted:
  701. X.RS
  702. X.PP
  703. X\fB;  &  (  )  \(br  ^  <  >  new-line  space  tab\fR
  704. X.RE
  705. X.PP
  706. XA character may be \fIquoted\fR (i.e., made to stand for itself) by preceding
  707. Xit with a \fB\e\fR.  The pair \fB\enew-line\fR is ignored.  All characters
  708. Xenclosed between a pair of single quote marks (\fB\(aa\(aa\fR), except a
  709. Xsingle quote, are quoted.  Inside double quote marks (\fB""\fR), parameter
  710. Xand command substitution occurs and \fB\e\fR quotes the characters \fB\e\fR,
  711. X\fB\(ga\fR, \fB"\fR, and \fB$\fR. \fB"$*"\fR is equivalent to \fB"$1 $2 ..."\fR,
  712. Xwhereas \fB"$@"\fR is equivalent to \fB"$1" "$2" ...\fR.
  713. X.SS Prompting
  714. XWhen used interactively, the shell prompts with the value of \fBPS1\fR
  715. Xbefore reading a command.  If at any time a new-line is typed and further
  716. Xinput is needed to complete a command, the secondary prompt (i.e., the value
  717. Xof \fB\s-1PS2\s+1\fR) is issued.
  718. X.PP
  719. XMany people like to have the shell provide them with useful information in
  720. Xtheir prompt.  To accommodate this, the shell recognises special sequences of
  721. Xcharacters in the values of \fBPS1\fR and \fBPS2\fR, and substitutes the
  722. Xappropriate information for them.  The special sequences and what they signify
  723. Xare:
  724. X.RS
  725. X.TP
  726. X\fB%d\fR
  727. XPlace the current date, in the form \s-1DAY DD-MM-YY\s+1 into the prompt.
  728. X.TP
  729. X\fB%e\fR
  730. XPlace the current event number (as defined by the \fBhistory\fR command) into
  731. Xthe prompt.  If history evaluation has been turned off (via \fBhistory -d\fR),
  732. Xno number will be substituted in (i.e. the \fB%e\fR will be removed).
  733. X.TP
  734. X\fB%n\fR
  735. XPlace the current working drive into the prompt.
  736. X.TP
  737. X\fB%p\fR
  738. XPlace the current working directory into the prompt.
  739. X.TP
  740. X\fB%t\fR
  741. XPlace the current time of day, in the form \s-1HH:MM\s+1 into the prompt.
  742. XThe time is on a 24 hour clock, i.e. 1:30 in the afternoon will be 13:30.
  743. X.TP
  744. X\fB%v\fR
  745. XPlace the MSDOS version number, in the form \s-1 MSDOS MM:MM\s+1 into the
  746. Xprompt.
  747. X.TP
  748. X\fB%%\fR
  749. XPlace the character \fI%\fR into the prompt.
  750. X.TP
  751. X\fB\exxx\fR
  752. XPlace the character \fI\exxx\fR into the prompt.  The processing of escape
  753. Xsequences is the same as that for \fBecho\fR.
  754. X.RE
  755. X.PP
  756. XSome of these facilities are of more use than others.
  757. X.SS Input/Output
  758. XBefore a command is executed, its input and output may be redirected using a
  759. Xspecial notation interpreted by the shell.  The following may appear anywhere
  760. Xin a simple-command or may precede or follow a \fIcommand\fR and are \fInot\fR
  761. Xpassed on to the invoked command; substitution occurs before \fIword\fR or
  762. X\fIdigit\fR is used:
  763. X.PP
  764. X.PD 0
  765. X.TP 14
  766. X\fB<word\fR
  767. XUse file \fIword\fR as standard input (file descriptor 0).
  768. X.TP
  769. X\fB>word\fR
  770. XUse file \fIword\fR as standard output (file descriptor 1).  If the file does
  771. Xnot exist it is created; otherwise, it is truncated to zero length.
  772. X.TP
  773. X\fB>\h@-.3m@>word\fR
  774. XUse file \fIword\fR as standard output.  If the file exists output is appended
  775. Xto it (by first seeking to the end-of-file); otherwise, the file is created.
  776. X.TP
  777. X\fB<\h@-.3m@<\fR\*(OK\fB-\fR\*(CK\fBword\fR
  778. XThe shell input is read up to a line that is the same as \fIword\fR, or to an
  779. Xend-of-file.  The resulting document becomes the standard input.  If any
  780. Xcharacter of \fIword\fR is quoted, no interpretation is placed upon the
  781. Xcharacters of the document; otherwise, parameter and command substitution
  782. Xoccurs, (unescaped) \fB\enew-line\fR is ignored, and \fB\e\fR must be used to
  783. Xquote the characters \fB\e\fR, \fB$\fR, \fB\(ga\fR, and the first character of
  784. X\fIword\fR.  If \fB-\fR is appended to \fB<\h@-.3m@<\fR, all leading tabs are
  785. Xstripped from \fIword\fR and from the document.
  786. X.TP
  787. X\fB<\h@-.1m@&digit\fR
  788. XUse the file associated with file descriptor \fIdigit\fR as standard input.
  789. XSimilarly for the standard output using \fB>\h@-.1m@&digit\fR.
  790. X.TP
  791. X\fB<\h@-.1m@&\h@-.1m@\-\fR
  792. XThe standard input is closed.  Similarly for the standard output using
  793. X\fB>\h@-.1m@&\h@-.1m@\-\fR.
  794. X.PD
  795. X.PP
  796. XIf any of the above is preceded by a digit, the file descriptor which will be
  797. Xassociated with the file is that specified by the digit (instead of the
  798. Xdefault 0 or 1).  For example:
  799. X.RS
  800. X.PP
  801. X\&... 2>&1
  802. X.RE
  803. X.PP
  804. Xassociates file descriptor 2 with the file currently associated with file
  805. Xdescriptor 1.
  806. X.PP
  807. XThe order in which redirections are specified is significant.  The shell
  808. Xevaluates redirections left-to-right.  For example:
  809. X.RS
  810. X.PP
  811. X\&... 1>\fIxxx\fR 2>&1
  812. X.RE
  813. X.PP
  814. Xfirst associates file descriptor 1 with file \fIxxx\fR.  It associates file
  815. Xdescriptor 2 with the file associated with file descriptor 1 (i.e. \fIxxx\fR).
  816. XIf the order of redirections were reversed, file descriptor 2 would be
  817. Xassociated with the terminal (assuming file descriptor 1 had been) and file
  818. Xdescriptor 1 would be associated with file \fIxxx\fR .
  819. X.PP
  820. XThe environment for the execution of a command contains the file descriptors
  821. Xof the invoking shell as modified by input/output specifications.
  822. X.PP
  823. XRedirection of output is not allowed in the restricted shell.
  824. X.SS Environment
  825. XThe \fIenvironment\fR (see \fIenviron\fR(5)) is a list of name-value pairs
  826. Xthat is passed to an executed program in the same way as a normal argument
  827. Xlist.  The shell interacts with the environment in several ways.  On invocation,
  828. Xthe shell scans the environment and creates a parameter for each name found,
  829. Xgiving it the corresponding value.  If the user modifies the value of any of
  830. Xthese parameters or creates new parameters, none of these affects the
  831. Xenvironment unless the \fBexport\fR command is used to bind the shell's
  832. Xparameter to the environment (see also \fBset -a\fR).  A parameter may be
  833. Xremoved from the environment with the \fBunset\fR command.  The environment
  834. Xseen by any executed command is thus composed of any unmodified name-value
  835. Xpairs originally inherited by the shell, minus any pairs removed by \fBunset\fR,
  836. Xplus any modifications or additions, all of which must be noted in \fBexport\fR
  837. Xcommands.
  838. X.PP
  839. XThe environment for any \fIsimple-command\fR may be augmented by prefixing it
  840. Xwith one or more assignments to parameters.  Thus:
  841. X.RS
  842. X.PP
  843. X\s-1TERM\s+1\(eq450 cmd args            and
  844. X.br
  845. X(export \s-1TERM\s+1; \s-1TERM\s+1\(eq450; cmd args)
  846. X.RE
  847. X.PP
  848. Xare equivalent (as far as the execution of \fIcmd\fR is concerned).
  849. X.PP
  850. XIf the \fB-k\fR flag is set, \fIall\fR keyword arguments are placed in the
  851. Xenvironment, even if they occur after the command name.  The following first
  852. Xprints \fBa\(eqb c\fR and \fBc\fR:
  853. X.PP
  854. X.RS
  855. X.nf
  856. Xecho a\(eqb c
  857. Xset -k
  858. Xecho a\(eqb c
  859. X.fi
  860. X.RE
  861. X.SS Signals
  862. XThe \s-1INTERRUPT\s+1 and \s-1QUIT\s+1 signals for an invoked command are
  863. Xignored if the command is followed by \fB&\fR; otherwise signals have the
  864. Xvalues inherited by the shell from its parent, with the exception of signal 11
  865. X(but see also the \fBtrap\fR command below).
  866. X.SS History
  867. XWhen reading input from an interactive terminal, a \(ga\(ga!\(aa\(aa at the
  868. Xstart of a line signals to the shell that it should attempt to perform a history
  869. Xsubsitution.  A history subsitution is a short-hand method which allows the
  870. Xuser to recall a previous command for execution or editing.  The recalled
  871. Xcommand is placed in the command line for editing or passing to the rest of
  872. Xthe shell for normal processing.  A history substitution takes the form:
  873. X.RS
  874. X.PP
  875. X\fB!\fR \*(OK \fIstr\fR \(br \fInum\fR \*(CK \fIterminator\fR
  876. X.RE
  877. X.PP
  878. X\fB!\fInum\fR will place the history command with the specified number
  879. Xin the command line.  \fB!\fIstr\fR will find the most recent command
  880. Xline that started with the characters in \fIstr\fR.
  881. X.PP
  882. XThe \fIterminator\fR determines what action is performed after the history
  883. Xline has been found.  If the original history command is entered using the
  884. X\fB<return>\fR key, the new command line is passed directly to the shell.
  885. XIf the \fB<end>\fR key is pressed, the new command line can be edited in the
  886. Xmanner described below.
  887. X.SS Command Line Editing
  888. XWhen reading input from an interactive terminal, certain keystrokes allow
  889. Xthe current input line to be edited.  The following keystrokes are
  890. Xavailable:
  891. X.TP
  892. X.SM "Cursor Right"
  893. XMove the cursor right one character
  894. X.TP
  895. X.SM "Control-Cursor Right"
  896. XMove the cursor right one word
  897. X.TP
  898. X.SM "Cursor Left"
  899. XMove the cursor left one character
  900. X.TP
  901. X.SM "Control-Cursor Left"
  902. XMove the cursor left one word
  903. X.TP
  904. X.SM "Cursor Up"
  905. XGet the previous command from the history file
  906. X.TP
  907. X.SM "Cursor Down"
  908. XGet the next command from the history file
  909. X.TP
  910. X.SM "Insert"
  911. XToggle insert/overwrite mode
  912. X.TP
  913. X.SM "Delete"
  914. XDelete the current character
  915. X.TP
  916. X.SM "Home"
  917. XMove the cursor to the start of the command
  918. X.TP
  919. X.SM "End"
  920. XMove the cursor to the end of the command, unless the first character of
  921. Xthe command is a \fB!\fR, in which case the appropriate history search is
  922. Xdone.
  923. X.TP
  924. X.SM "Control-End"
  925. XDelete to the end of the line
  926. X.TP
  927. X.SM "Page-Up"
  928. XSearch backwards from the current history command for the next match against
  929. Xthe last history request.  This command can only be used after \fBEnd\fR has
  930. Xbeen used to select a history line.
  931. X.TP
  932. X.SM "Page-Down"
  933. XSearch forewards from the current history command for the next match against
  934. Xthe last history request.  This command can only be used after \fBEnd\fR has
  935. Xbeen used to select a history line.
  936. X.TP
  937. X.SM "Backspace"
  938. XMove the cursor back one character, erasing the current character.
  939. X.TP
  940. X.SM "Return"
  941. XExecute the command line, unless the first character of the command is a
  942. X\fB!\fR, in which case the appropriate history processing is done.
  943. X.PD
  944. X.RE
  945. X.SS Execution
  946. XEach time a command is executed, the above substitutions are carried out.  If
  947. Xthe command name matches one of the \fISpecial Commands\fR listed below, it
  948. Xis executed in the shell process.  If the command name does not match a
  949. X\fISpecial Command\fR, but matches the name of a defined function, the
  950. Xfunction is executed in the shell process (note how this differs from the
  951. Xexecution of shell procedures).  The positional parameters \fB$1\fR,
  952. X\fB$2\fR, ....  are set to the arguments of the function.  If the command
  953. Xname matches neither a \fISpecial Command\fR nor the name of a defined function,
  954. Xa new process is created and an attempt is made to execute the command via
  955. X\fIexec\fR(2).
  956. X.PP
  957. XThe shell parameter \fBPATH\fR defines the search path for the directory
  958. Xcontaining the command.  Alternative directory names are separated by a
  959. Xsemi-colon (\fB;\fR).  The default path is \fB;c:/bin;c:/usr/bin\fR (specifying
  960. Xthe current directory, \fBc:/bin\fR, and \fBc:/usr/bin\fR, in that order).
  961. XNote that the current directory is specified by a null path name, which can
  962. Xappear immediately after the equal sign or between the semi-colon delimiters
  963. Xanywhere else in the path list.  If the command name contains a \fB/\fR or
  964. Xstarts with \fBx:\fR (where x is a drive letter) the search path is not used;
  965. Xsuch commands will not be executed by the restricted shell.  Otherwise, each
  966. Xdirectory in the path is searched for an executable file.
  967. X.PP
  968. XIf the file does not have a .com or .exe extension, it is opened and the first
  969. X5 characters are read.  If the first 5 characters are the string
  970. X\fB#!sh\\n\fR it is assumed to be a file containing shell commands.  Note
  971. Xthat the shell will check the file and if that file does not exist or is not a
  972. Xscript, it will try the file with an extension of \fB.sh\fR.  If a \fB.sh\fR
  973. Xfile is found, that will be processed.  A sub-shell is spawned to read it.
  974. XA parenthesized command is also executed in a sub-shell.
  975. X.SS Special Commands
  976. XInput/output redirection is permitted for these commands.  File descriptor 1
  977. Xis the default output location.
  978. X.PP
  979. X.PD 0
  980. X.TP
  981. X\fB:\fR
  982. XNo effect; the command does nothing.  A zero exit code is returned.
  983. X.TP
  984. X\fIletter\fB:\fR
  985. XSelect the drive specified by \fIletter\fR.
  986. X.TP
  987. X\fB\&. \fIfile\fR
  988. XRead and execute commands from \fIfile\fR and return.  The search path
  989. Xspecified by \fBPATH\fR is used to find the directory containing \fIfile\fR.
  990. X.TP
  991. X\fBbreak\fR \*(OK \fIn\fR \*(CK
  992. XExit from the enclosing \fBfor\fR or \fBwhile\fR loop, if any.  If \fIn\fR is
  993. Xspecified, break \fIn\fR levels.
  994. X.TP
  995. X\fBcontinue\fR \*(OK \fIn\fR \*(CK
  996. XResume the next iteration of the enclosing \fBfor\fR or \fBwhile\fR loop.  If
  997. X\fIn\fR is specified, resume at the \fIn\fR-th enclosing loop.
  998. X.TP
  999. X\fBcd\fR \*(OK \fIarg\fR \*(CK
  1000. XChange the current directory to \fIarg\fR.  The shell parameter \fBHOME\fR is
  1001. Xthe default \fIarg\fR.  The shell parameter \fBCDPATH\fR defines the search
  1002. Xpath for the directory containing \fIarg\fR.  Alternative directory names are
  1003. Xseparated by a semi-colon (\fB;\fR).  The default path is \fB<null>\fR
  1004. X(specifying the current directory).  Note that the current directory is
  1005. Xspecified by a null path name, which can appear immediately after the equal
  1006. Xsign or between the semi-colon delimiters anywhere else in the path list.
  1007. XIf \fIarg\fR begins with a \fB/\fR or \fBx:\fR (where x is a drive letter),
  1008. Xthe search path is not used.  Otherwise, each directory in the path is searched
  1009. Xfor \fIarg\fR.  The \fIcd\fR command may not be executed by \fIrsh\fR.
  1010. X.TP
  1011. X\fBecho\fR \*(OK \fIarg\fR ... \*(CK
  1012. XEcho arguments. \fBEcho\fR writes its arguments separated by blanks and
  1013. Xterminated by a new-line on the standard output.  It also understands C-like
  1014. Xescape conventions; beware of conflicts with the shell's use of \fB\e\fR:
  1015. X.PP
  1016. X.RS
  1017. X.PD 0
  1018. X.TP
  1019. X\fB\eb\fR
  1020. Xbackspace
  1021. X.TP
  1022. X\fB\ec\fR
  1023. Xprint line without new-line
  1024. X.TP
  1025. X\fB\ef\fR
  1026. Xform-feed
  1027. X.TP
  1028. X\fB\en\fR
  1029. Xnew-line
  1030. X.TP
  1031. X\fB\er\fR
  1032. Xcarriage return
  1033. X.TP
  1034. X\fB\et\fR
  1035. Xtab
  1036. X.TP
  1037. X\fB\ev\fR
  1038. Xvertical tab
  1039. X.TP
  1040. X\fB\e\e\fR
  1041. Xbackslash
  1042. X.TP
  1043. X\fB\e\fIn\fR
  1044. Xthe 8-bit character whose \s-1ASCII\s0 code is the 1-, 2- or 3-digit octal
  1045. Xnumber \fIn\fR, which must start with a zero.
  1046. X.PD
  1047. X.PP
  1048. X\fIEcho\fR is useful for producing diagnostics in command files and for
  1049. Xsending known data into a pipe.
  1050. X.RE
  1051. X.TP
  1052. X\fBeval\fR \*(OK \fIarg\fR ... \*(CK
  1053. XThe arguments are read as input to the shell and the resulting command(s)
  1054. Xexecuted.
  1055. X.TP
  1056. X\fBexec\fR \*(OK \fIarg\fR ... \*(CK
  1057. XThe command specified by the arguments is executed in place of this shell
  1058. Xwithout creating a new process.  Input/output arguments may appear and, if no
  1059. Xother arguments are given, cause the shell input/output to be modified.
  1060. X.TP
  1061. X\fBexit\fR \*(OK \fIn\fR \*(CK
  1062. XCauses a shell to exit with the exit status specified by \fIn\fR.
  1063. XIf \fIn\fR is omitted the exit status is that of the last command executed
  1064. X(an end-of-file will also cause the shell to exit.)
  1065. X.TP
  1066. X\fBexport\fR \*(OK \fIname\fR ... \*(CK
  1067. XThe given \fIname\fRs are marked for automatic export to the \fIenvironment\fR
  1068. Xof subsequently-executed commands.  If no arguments are given, a list of all
  1069. Xnames that are exported in this shell is printed.  Function names may \fInot\fR
  1070. Xbe exported.
  1071. X.TP
  1072. X\fBgetopt\fR \fIoptstring name\fR \*(OK \fIargs\fR ... \*(CK
  1073. XParse command options and write them to standard output.  \fBGetopt\fR is used
  1074. Xto break up options in command lines for easy parsing by shell procedures and
  1075. Xto check for legal options.  \fIOptstring\fR is a string of recognized option
  1076. Xletters (see \fIgetopt\fR(3C)); if a letter is followed by a colon, the option
  1077. Xis expected to have an argument which may or may not be separated from it by
  1078. Xwhite space.  The special option \fB\-\-\fP is used to delimit the end of the
  1079. Xoptions.  If it is used explicitly, \fBgetopt\fR will recognize it; otherwise,
  1080. X\fBgetopt\fR will generate it; in either case, \fBgetopt\fR will place it at
  1081. Xthe end of the options.  Each option is preceded by a \fB-\fR and is in its
  1082. Xown positional parameter; each option argument is also parsed into its own
  1083. Xpositional parameter.
  1084. X.sp
  1085. XThe following code fragment shows how one might process the arguments for a
  1086. Xcommand that can take the options \fBa\fR or \fBb\fR, as well as the option
  1087. X\fBo\fR, which requires an argument:
  1088. X.sp
  1089. X.RS
  1090. X.nf
  1091. X.ss 18
  1092. X.ta +.5i +1i
  1093. Xset -- \(gagetopt abo: $*\(ga
  1094. Xif [ $? !\(eq 0 ]
  1095. Xthen
  1096. X    echo $\s-1USAGE\s+1
  1097. X    exit 2
  1098. Xfi
  1099. Xfor i in $\(**
  1100. Xdo
  1101. X    case $i in
  1102. X    \-a \(bv \-b)    \s-1FLAG\s+1\(eq$i; shift;;
  1103. X    \-o)    \s-1OARG\s+1\(eq$2; shift 2;;
  1104. X    \-\-)    shift; break;;
  1105. X    esac
  1106. Xdone
  1107. X.fi
  1108. X.ta
  1109. X.ss 12
  1110. X.sp
  1111. XThis code will accept any of the following as equivalent:
  1112. X.sp
  1113. X.nf
  1114. X.ss 18
  1115. Xcmd \-aoarg file file
  1116. Xcmd \-a \-o arg file file
  1117. Xcmd \-oarg \-a file file
  1118. Xcmd \-a \-oarg \-\- file file
  1119. X.fi
  1120. X.ss 12
  1121. X.RE
  1122. X.TP
  1123. X\fBhistory\fR \*(OK \fB-dei\fR \*(CK
  1124. XThe \fBhistory\fR command, with no arguments, will print all the commands that
  1125. Xare currently saved in the shell's history buffers.  As new commands are
  1126. Xexecuted, and space in the buffers runs out, old commands will be deleted.  The
  1127. X\fBhistory\fR commands prints out the stored commands with sequence numbers.
  1128. XNegative numbered commands, through command number zero, are commands that were
  1129. Xretrieved from the saved history file.  Commands starting at one were entered
  1130. Xduring the current login session.  If a saved command contains embedded
  1131. Xnewlines, these will be printed out as the sequence \fB\en\fR, so that
  1132. Xindividual command stay on one line.
  1133. X.sp
  1134. XThe arguments changes the way the shell processes history information as
  1135. Xfollows:
  1136. X.RS
  1137. X.TP
  1138. X\fB-d\fR
  1139. XDisable the saving of commands in the history file.
  1140. X.TP
  1141. X\fB-e\fR
  1142. XEnable the saving of commands in the history file.
  1143. X.TP
  1144. X\fB-i\fR
  1145. XInitialise the history file.
  1146. X.RE
  1147. X.TP
  1148. X\fBmsdos\fR \*(OK \fIname\fR ... \*(CK
  1149. XThe given \fIname\fRs are marked \fImsdos\fR format and if the \fB-m\fR flag
  1150. Xis set, the values of the these \fIname\fRs are exported to child processes
  1151. Xwith the any slashes in the value replaced by backslashes.
  1152. X.TP
  1153. X\fBpwd\fR
  1154. XPrint the current working directory.  
  1155. X.TP
  1156. X\fBread\fR \*(OK \fIname\fR ... \*(CK
  1157. XOne line is read from the standard input and the first word is assigned to the
  1158. Xfirst \fIname\fR, the second word to the second \fIname\fR, etc., with leftover
  1159. Xwords assigned to the last \fIname\fR.  The return code is 0 unless an
  1160. Xend-of-file is encountered.
  1161. X.TP
  1162. X\fBreadonly\fR \*(OK \fIname\fR ... \*(CK
  1163. XThe given \fIname\fRs are marked \fIreadonly\fR and the values of the these
  1164. X\fIname\fRs may not be changed by subsequent assignment.  If no arguments are
  1165. Xgiven, a list of all \fIreadonly\fR names is printed.
  1166. X.TP
  1167. X\fBreturn\fR \*(OK \fIn\fR \*(CK
  1168. XCauses a function to exit with the return value specified by \fIn\fR.  If
  1169. X\fIn\fR is omitted, the return status is that of the last command executed.
  1170. X.TP
  1171. X\fBset\fR \*(OK \fB--aefkmntuvx\fR \*(OK \fIarg\fR ... \*(CK \*(CK
  1172. X.RS
  1173. X.TP
  1174. X\fB-a\fR
  1175. XMark variables which are modified or created for export.
  1176. X.TP
  1177. X\fB-e\fR
  1178. XExit immediately if a command exits with a non-zero exit status.
  1179. X.TP
  1180. X\fB-f\fR
  1181. XDisable file name generation
  1182. X.TP
  1183. X\fB-k\fR
  1184. XAll keyword arguments are placed in the environment for a command, not just
  1185. Xthose that precede the command name.
  1186. X.TP
  1187. X\fB-m\fR
  1188. XFor those variables marked as \fBmsdos\fR variables, the values are
  1189. Xexported to child processes with the slashes replaced by backslashes.  Most
  1190. XMSDOS utilities do not care if a file name contains a slash or backslash as
  1191. Xa directory separator.  However, some like the \fIlinker\fR require
  1192. Xbackslashes in the value of the \fBLIB\fR variable.
  1193. X.TP
  1194. X\fB-n\fR
  1195. XRead commands but do not execute them.
  1196. X.TP
  1197. X\fB-t\fR
  1198. XExit after reading and executing one command.
  1199. X.TP
  1200. X\fB-u\fR
  1201. XTreat unset variables as an error when substituting.
  1202. X.TP
  1203. X\fB-v\fR
  1204. XPrint shell input lines as they are read.
  1205. X.TP
  1206. X\fB-x\fR
  1207. XPrint commands and their arguments as they are executed.
  1208. X.TP
  1209. X\fB--\fR
  1210. XDo not change any of the flags; useful in setting \fB$1\fR to \fB\-\fR.
  1211. X.PP
  1212. XUsing \fB+\fR rather than \fB-\fR causes these flags to be turned off.  These
  1213. Xflags can also be used upon invocation of the shell.  The current set of flags
  1214. Xmay be found in \fB$-\fR.  The remaining arguments are positional parameters
  1215. Xand are assigned, in order, to \fB$1\fR, \fB$2\fR, ....  If no arguments
  1216. Xare given the values of all names are printed.
  1217. X.RE
  1218. X.TP
  1219. X\fBshift\fR \*(OK \fIn\fR \*(CK
  1220. X.br
  1221. XThe positional parameters from \fB$n+1\fR ...  are renamed \fB$1\fR ....  If
  1222. X\fIn\fR is not given, it is assumed to be 1.
  1223. X.TP
  1224. X\fBswap\fR \*(OK \fIoptions\fR \*(CK
  1225. XThis command defines how the shell will handle swapping.  The options are
  1226. X.RS
  1227. X.TP
  1228. X\fBoff\fR
  1229. XDisable swapping.  The shell remains in memory whilst the child is running
  1230. Xand reduces the available memory by about 200K (depending on the size of
  1231. Xthe environment and history).
  1232. X.TP
  1233. X\fBon\fR
  1234. XEnable all devices.  The shell will swap out to either expanded or extended
  1235. Xmemory or to disk, execute the command and then swap back in.  Whilest
  1236. Xswapped, the shell reduces the available memory by about 3K.
  1237. X.TP
  1238. X\fBexpand\fR
  1239. XEnable swapping to Expanded Memory.  The EMS drive must exist on your
  1240. Xsystem for this to work.
  1241. X.TP
  1242. X\fBextent\fR \*(OK \fIstart address\fR \*(CK
  1243. XEnable swapping to Extended Memory.  The optional start address defines the
  1244. Xbased address in the Extended Memory at which point the shell writes its
  1245. Xswap area.  The default location is \fI0x100000\fR.
  1246. X.TP
  1247. X\fBdisk\fR
  1248. XEnable swapping to disk.  The shell creates a temporary file and saves
  1249. Xitself in it.  On completion, the file is deleted.  This is the slowest method
  1250. Xof swapping.
  1251. X.PD
  1252. X.PP
  1253. XWith no options, the current swapping options are displayed.
  1254. X.RE
  1255. X.TP
  1256. X\fBtest \fIexpr\fR or \fB\*(OK \fIexpr\fB \*(CK\fR
  1257. XEvaluate conditional expressions.  \fBTest\fR evaluates the expression
  1258. X\fIexpr\fR and, if its value is true, returns a zero (true) exit status;
  1259. Xotherwise, a non-zero (false) exit status is returned; \fBtest\fR also returns
  1260. Xa non-zero exit status if there are no arguments.  The following primitives
  1261. Xare used to construct \fBexpr\fR:
  1262. X.RS
  1263. X.TP 12
  1264. X\fB-r \fIfile\fR
  1265. Xtrue if \fIfile\fR exists and is readable.
  1266. X.TP
  1267. X\fB-w \fIfile\fR
  1268. Xtrue if \fIfile\fR exists and is writable.
  1269. X.TP
  1270. X\fB-x \fIfile\fR
  1271. Xtrue if \fIfile\fR exists and is executable.
  1272. X.TP
  1273. X\fB-f \fIfile\fR
  1274. Xtrue if \fIfile\fR exists and is a regular file.
  1275. X.TP
  1276. X\fB-d \fIfile\fR
  1277. Xtrue if \fIfile\fR exists and is a directory.
  1278. X.TP
  1279. X\fB-c \fIfile\fR
  1280. Xtrue if \fIfile\fR exists and is a character special file.
  1281. X.TP
  1282. X\fB-b \fIfile\fR
  1283. Xtrue if \fIfile\fR exists and is a block special file.
  1284. X.TP
  1285. X\fB-s \fIfile\fR
  1286. Xtrue if \fIfile\fR exists and has a size greater than zero.
  1287. X.TP
  1288. X\fB-t\fR \*(OK \fIfildes\fR \*(CK
  1289. Xtrue if the open file whose file descriptor number is \fIfildes\fR (1 by
  1290. Xdefault) is associated with a terminal device.
  1291. X.TP
  1292. X\fB-n \fIs1\fR
  1293. Xtrue if the length of the string \fIs1\fR is zero.
  1294. X.TP
  1295. X\fB-n \fIs1\fR
  1296. Xtrue if the length of the string \fIs1\fR is non-zero.
  1297. X.TP
  1298. X\fIs1 \fB\(eq\fI s2\fR
  1299. Xtrue if strings \fIs1\fR and \fIs2\fR are identical.
  1300. X.TP
  1301. X\fIs1 \fB!\(eq\fI s2\fR
  1302. Xtrue if strings \fIs1\fR and \fIs2\fR are \fInot\fR identical.
  1303. X.TP
  1304. X\fIs1\fR
  1305. Xtrue if \fIs1\fR is \fInot\fR the null string.
  1306. X.TP
  1307. X\fIn1 \fB-eq \fIn2\fR
  1308. Xtrue if the integers \fIn1\fR and \fIn2\fR are algebraically equal.  Any of
  1309. Xthe comparisons \fB-ne\fR, \fB-gt\fR, \fB-ge\fR, \fB-lt\fR, and \fB-le\fR
  1310. Xmay be used in place of \fBR-eq\fR.
  1311. X.PP
  1312. XThese primaries may be combined with the following operators:
  1313. X.TP  12
  1314. X\fB!\fR
  1315. Xunary negation operator.
  1316. X.TP
  1317. X\fB-a\fR
  1318. Xbinary \fIand\fR operator.
  1319. X.TP
  1320. X\fB-o\fR
  1321. Xbinary \fIor\fR operator (\fB-a\fR has higher precedence than \fB-o\fR).
  1322. X.TP
  1323. X\fB(\fR expr \fB)\fR
  1324. Xparentheses for grouping.
  1325. X.PP
  1326. XNotice that all the operators and flags are separate arguments to \fBtest\fR.
  1327. XNotice also that parentheses are meaningful to the shell and, therefore,
  1328. Xmust be escaped.
  1329. X.RE
  1330. X.TP
  1331. X\fBtrap\fR \*(OK \fIarg\fR \*(CK \*(OK \fIn\fR \*(CK ...
  1332. XThe command \fIarg\fR is to be read and executed when the shell receives
  1333. Xsignal(s) \fIn\fR.  (Note that \fIarg\fR is scanned once when the trap is set
  1334. Xand once when the trap is taken.) Trap commands are executed in order of
  1335. Xsignal number.  Any attempt to set a trap on a signal that was ignored on
  1336. Xentry to the current shell is ineffective.  An attempt to trap on signal 11
  1337. X(memory fault) produces an error.  If \fIarg\fR is absent all trap(s) \fIn\fR
  1338. Xare reset to their original values.  If \fIarg\fR is the null string this
  1339. Xsignal is ignored by the shell and by the commands it invokes.  If \fIn\fR is
  1340. X0 the command \fIarg\fR is executed on exit from the shell.  The \fBtrap\fR
  1341. Xcommand with no arguments prints a list of commands associated with each
  1342. Xsignal number.
  1343. X.TP
  1344. X\fBtype\fR \*(OK \fIname\fR ... \*(CK
  1345. XFor each \fIname\fR, indicate how it would be interpreted if used as a command
  1346. Xname.
  1347. X.TP
  1348. X\fBumask\fR \*(OK \fInnn\fR \*(CK
  1349. XThe user file-creation mask is set to \fInnn\fR (see \fIumask\fR(2)).  If
  1350. X\fInnn\fR is omitted, the current value of the mask is printed.
  1351. X.TP
  1352. X\fBunset\fR \*(OK \fIname\fR ... \*(CK
  1353. XFor each \fIname\fR, remove the corresponding variable or function.  The
  1354. Xvariables \fB\s-1PATH\s+1\fR, \fB\s-1PS1\s+1\fR, \fB\s-1PS2\s+1\fR, and
  1355. X\fB\s-1IFS\s+1\fR cannot be unset.
  1356. X.TP
  1357. X\fBver\fR
  1358. XDisplay the current version of the shell.
  1359. X.PD
  1360. X.PP
  1361. X.SS Invocation
  1362. XIf the shell is invoked through \fIexec\fR(2) and the first character of
  1363. Xargument zero is \fB-\fR or the \fB-0\fR(zero) switch is in the invokation line,
  1364. Xcommands are initially read from \fB/etc/profile.sh\fR and from
  1365. X\fB\s-1$HOME\s+1/profile.sh\fR, if such files exist.  Thereafter, commands are
  1366. Xread as described below, which is also the case when the shell is invoked as
  1367. X\fB/bin/sh\fR.  The flags below are interpreted by the shell on invocation only;
  1368. XNote that unless the \fB-c\fR or \fB-s\fR flag is specified, the first argument
  1369. Xis assumed to be the name of a file containing commands, and the remaining
  1370. Xarguments are passed as positional parameters to that command file:
  1371. X.PP
  1372. X.PD 0
  1373. X.TP 10
  1374. X\fB-c\fR string
  1375. XIf the \fB-c\fR flag is present commands are read from \fIstring\fR.
  1376. X.TP
  1377. X\fB-s\fR
  1378. XIf the \fB-s\fR flag is present or if no arguments remain commands are read
  1379. Xfrom the standard input.  Any remaining arguments specify the positional
  1380. Xparameters.  Shell output (except for \fISpecial Commands\fR) is written to
  1381. Xfile descriptor 2.
  1382. X.TP
  1383. X\fB-i\fR
  1384. XIf the \fB-i\fR flag is present or if the shell input and output are attached
  1385. Xto a terminal, this shell is \fIinteractive\fR.  In this case, the
  1386. X\s-1TERMINATE\s+1 signal is ignored and the \s-1INTERRUPT\s+1 signal is caught
  1387. Xand ignored.  In all cases, the \s-1QUIT\s+1 signal is ignored by the shell.
  1388. X.TP
  1389. X\fB-r\fR
  1390. XIf the \fB-r\fR flag is present, the shell is a restricted shell.
  1391. X.TP
  1392. X\fB-0\fR(zero)
  1393. XIf the \fB-0\fR(zero) flag is present, this has the same effect as starting the
  1394. Xshell with the first character of argument zero as a \fB-\fR (see above).
  1395. X.PD
  1396. X.PP
  1397. XThe remaining flags and arguments are described under the \fBset\fR command
  1398. Xabove.
  1399. X.SS Rsh Only
  1400. X\fIRsh\fR is used to set up login names and execution environments whose
  1401. Xcapabilities are more controlled than those of the standard shell.  The
  1402. Xactions of \fIrsh\fR are identical to those of \fIsh\fR, except that the
  1403. Xfollowing are disallowed:
  1404. X.RS
  1405. X.PD 0
  1406. X.PP
  1407. Xchanging directory (see \fIcd\fR(1)),
  1408. X.br
  1409. Xsetting the value of \fB$PATH\fR
  1410. X.br
  1411. Xspecifying path or command names containing \fB/\fR,
  1412. X.br
  1413. Xredirecting output (\fB>\fR and \fB>>\fR).
  1414. X.PD
  1415. X.RE
  1416. X.PP
  1417. XThe restrictions above are enforced after \fBprofile.sh\fR is interpreted.
  1418. X.PP
  1419. XWhen a command to be executed is found to be a shell procedure, \fIrsh\fR
  1420. Xinvokes \fIsh\fR to execute it.  Thus, it is possible to provide to the
  1421. Xend-user shell procedures that have access to the full power of the standard
  1422. Xshell, while imposing a limited menu of commands; this scheme assumes that the
  1423. Xend-user does not have write and execute permissions in the same directory.
  1424. X.PP
  1425. XThe net effect of these rules is that the writer of the \fBprofile.sh\fR has
  1426. Xcomplete control over user actions, by performing guaranteed setup actions
  1427. Xand leaving the user in an appropriate directory (probably \fInot\fR the login
  1428. Xdirectory).
  1429. X.PP
  1430. XThe system administrator often sets up a directory of commands (i.e.,
  1431. X\fB/usr/rbin\fR) that can be safely invoked by \fIrsh\fR.  Some systems also
  1432. Xprovide a restricted editor \fIred\fR.
  1433. X.SH EXIT STATUS
  1434. XErrors detected by the shell, such as syntax errors, cause the shell to return
  1435. Xa non-zero exit status.  If the shell is being used non-interactively execution
  1436. Xof the shell file is abandoned.  Otherwise, the shell returns the exit status of
  1437. Xthe last command executed (see also the \fBexit\fR command above).
  1438. X.SH FILES
  1439. X/etc/profile.sh
  1440. X.br
  1441. X\s-1$HOME\s+1/profile.sh
  1442. X.br
  1443. X\s-1$TMP\s+1/sh\(**
  1444. X.SH LIMIITATIONS
  1445. XAny TSR (Terminate Stay Resident) programs must be loaded before loading
  1446. X\fISh\fR as the shell will overwrite the TSR when it reloads itself after
  1447. Xswapping out.
  1448. X.SH SEE ALSO
  1449. Xcd(1),
  1450. Xenv(1),
  1451. Xtest(1),
  1452. Xumask(1).
  1453. X.br
  1454. Xdup(2),
  1455. Xexec(2),
  1456. Xpipe(2),
  1457. Xsignal(2),
  1458. Xumask(2),
  1459. Xwait(2),
  1460. Xprofile(4),
  1461. Xenviron(5) in the
  1462. X\fI\s-1UNIX\s+1 System Programmer Reference Manual\fR.
  1463. SHAR_EOF
  1464. chmod 0644 sh.1 || echo "restore of sh.1 fails"
  1465. set `wc -c sh.1`;Sum=$1
  1466. if test "$Sum" != "42496"
  1467. then echo original size 42496, current size $Sum;fi
  1468. echo "x - extracting include/Changes (Text)"
  1469. sed 's/^X//' << 'SHAR_EOF' > include/Changes &&
  1470. XAdd to fcntl.h the following 2 lines
  1471. X
  1472. Xextern int _CDECL    open    (char *, int, ...);
  1473. Xextern int _CDECL    creat    (char *, int);
  1474. X
  1475. XAdd to limits.h the following 2 lines
  1476. X
  1477. X#define PATH_MAX    130        /* Maximum path length        */
  1478. X#define NAME_MAX    14        /* Maximum file name length    */
  1479. X
  1480. XAdd to stdio.h the following 2 lines
  1481. X
  1482. Xextern FILE * _CDECL    popen(char *, char *);
  1483. Xextern int _CDECL    pclose(FILE *);
  1484. X
  1485. XAdd to stdlib.h the following 8 lines
  1486. X
  1487. Xextern int _CDECL        optind;
  1488. Xextern int _CDECL        opterr;
  1489. Xextern int _CDECL        optind;
  1490. Xextern int _CDECL        optopt;
  1491. Xextern int _CDECL        optvar;
  1492. Xextern char * _CDECL        optarg;
  1493. Xextern int _CDECL        getopt    (int, char **, char *);
  1494. Xextern int _CDECL        pnmatch    (char *, char *, int);
  1495. X
  1496. XAdd to sys/stat.h the following 10 lines
  1497. X
  1498. X/* Tests for file types */
  1499. X
  1500. X#define    S_IFBLK        0060000        /* block special        */
  1501. X
  1502. X#define S_ISDIR(m)    ((((m) & S_IFMT) == S_IFDIR))
  1503. X#define S_ISCHR(m)    ((((m) & S_IFMT) == S_IFCHR))
  1504. X#define S_ISREG(m)    ((((m) & S_IFMT) == S_IFREG))
  1505. X#define S_ISBLK(m)    ((((m) & S_IFMT) == S_IFBLK))
  1506. Xextern int CDECL    chmod    (char *, int);
  1507. Xextern int CDECL    umask    (int);
  1508. X
  1509. XAdd to sys/types.h the following 32 lines
  1510. X
  1511. X#ifndef _USHORT_T_DEFINED
  1512. Xtypedef unsigned short    ushort;
  1513. X#define _USHORT_T_DEFINED
  1514. X#endif
  1515. X
  1516. X#ifndef _MODE_T_DEFINED
  1517. Xtypedef unsigned short    mode_t;
  1518. X#define _MODE_T_DEFINED
  1519. X#endif
  1520. X
  1521. X#ifndef _PID_T_DEFINED
  1522. Xtypedef int        pid_t;
  1523. X#define _PID_T_DEFINED
  1524. X#endif
  1525. X
  1526. X#ifndef _GID_T_DEFINED
  1527. Xtypedef int        gid_t;
  1528. X#define _GID_T_DEFINED
  1529. X#endif
  1530. X
  1531. X#ifndef _UID_T_DEFINED
  1532. Xtypedef int        uid_t;
  1533. X#define _UID_T_DEFINED
  1534. X#endif
  1535. X
  1536. X#ifndef _BOOL_T_DEFINED
  1537. Xtypedef char        bool;    /* Boolean: 0 = false, 1 = true        */
  1538. X#define FALSE    ((bool)0)    /* Boolean 'false'            */
  1539. X#define TRUE    ((bool)1)    /* Boolean 'true'            */
  1540. X#define _BOOL_T_DEFINED
  1541. X#endif
  1542. X
  1543. SHAR_EOF
  1544. chmod 0644 include/Changes || echo "restore of include/Changes fails"
  1545. set `wc -c include/Changes`;Sum=$1
  1546. if test "$Sum" != "1716"
  1547. then echo original size 1716, current size $Sum;fi
  1548. echo "x - extracting include/sys/dirent.h (Text)"
  1549. sed 's/^X//' << 'SHAR_EOF' > include/sys/dirent.h &&
  1550. X/* <sys/dirent.h> -- file system independent directory entry (SVR3) */
  1551. X#ifndef _SYS_DIRENT_H
  1552. X#define _SYS_DIRENT_H
  1553. X
  1554. X#ifndef MSDOS
  1555. X#define    MAXNAMLEN    512    /* maximum filename length        */
  1556. X#else
  1557. X#define    MAXNAMLEN    13    /* maximum filename length        */
  1558. X#endif
  1559. X
  1560. X#ifndef NAME_MAX
  1561. X#define    NAME_MAX    (MAXNAMLEN - 1)
  1562. X#endif
  1563. X
  1564. Xstruct dirent            /* data from getdents()/readdir()    */
  1565. X{
  1566. X    ino_t    d_ino;        /* inode number of entry        */
  1567. X    off_t    d_off;        /* offset of disk directory entry    */
  1568. X    ushort    d_reclen;    /* length of this record        */
  1569. X#ifndef MSDOS
  1570. X    char    d_name[1];    /* name of file                */
  1571. X#else
  1572. X    char    d_name[MAXNAMLEN + 1];
  1573. X#endif
  1574. X};
  1575. X
  1576. X#ifdef BSD_SYSV            /* (e.g., when compiling getdents.c)    */
  1577. Xextern struct dirent    __dirent;    /* (not actually used) */
  1578. X
  1579. X                /* The following is portable, although    */
  1580. X                /* rather silly.            */
  1581. X#define    DIRENTBASESIZ        (__dirent.d_name - (char *)&__dirent.d_ino)
  1582. X
  1583. X#else
  1584. X
  1585. X/* The following nonportable ugliness could have been avoided by defining
  1586. X * DIRENTSIZ and DIRENTBASESIZ to also have (struct dirent *) arguments.
  1587. X * There shouldn't be any problem if you avoid using the DIRENTSIZ() macro.
  1588. X */
  1589. X
  1590. X#define    DIRENTBASESIZ        (((struct dirent *)0)->d_name \
  1591. X                - (char *)&((struct dirent *)0)->d_ino)
  1592. X#endif
  1593. X
  1594. X#define    DIRENTSIZ(namlen)    ((DIRENTBASESIZ + sizeof(long) + (namlen)) \
  1595. X                / sizeof(long) * sizeof(long))
  1596. X
  1597. X#endif
  1598. SHAR_EOF
  1599. chmod 0644 include/sys/dirent.h || echo "restore of include/sys/dirent.h fails"
  1600. set `wc -c include/sys/dirent.h`;Sum=$1
  1601. if test "$Sum" != "1331"
  1602. then echo original size 1331, current size $Sum;fi
  1603. echo "x - extracting include/sys/proto.h (Text)"
  1604. sed 's/^X//' << 'SHAR_EOF' > include/sys/proto.h &&
  1605. X/*
  1606. X * Prototype definitions for Standard and Non-standard compilers
  1607. X */
  1608. X
  1609. X#undef _PROTO
  1610. X#undef _CDECL
  1611. X#undef _NEAR
  1612. X
  1613. X#ifdef MSDOS
  1614. X#  ifndef NO_EXT_KEYS                /* extensions enabled */
  1615. X#    define _CDECL    cdecl
  1616. X#    define _NEAR    near
  1617. X#  else 
  1618. X#    define _CDECL
  1619. X#    define _NEAR
  1620. X#  endif 
  1621. X#else
  1622. X#    define _CDECL
  1623. X#endif
  1624. X
  1625. X#ifdef __STDC__
  1626. X#  define _PROTO(p)    p
  1627. X#else
  1628. X#  define _PROTO(p)    ()
  1629. X#  undef  const
  1630. X#endif
  1631. SHAR_EOF
  1632. chmod 0644 include/sys/proto.h || echo "restore of include/sys/proto.h fails"
  1633. set `wc -c include/sys/proto.h`;Sum=$1
  1634. if test "$Sum" != "405"
  1635. then echo original size 405, current size $Sum;fi
  1636. echo "x - extracting include/dirent.h (Text)"
  1637. sed 's/^X//' << 'SHAR_EOF' > include/dirent.h &&
  1638. X/* <dirent.h> -- definitions for SVR3 directory access routines */
  1639. X#ifndef _DIRENT_H
  1640. X#define _DIRENT_H
  1641. X
  1642. X#include <sys/types.h>
  1643. X#include <limits.h>
  1644. X#include <sys/dirent.h>
  1645. X#include <sys/proto.h>
  1646. X
  1647. X#ifndef NULL
  1648. X#  ifdef MSDOS
  1649. X#    if (defined(M_I86SM) || defined(M_I86MM))
  1650. X#      define NULL    0
  1651. X#    else
  1652. X#      if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
  1653. X#        define NULL    0L
  1654. X#      endif
  1655. X#    endif
  1656. X#  else
  1657. X#    define NULL    0
  1658. X#  endif
  1659. X#endif
  1660. X
  1661. X#define    DIRBUF    8192        /* buffer size for fs-indep. dirs    */
  1662. X                /* must in general be larger than the    */
  1663. X                /* filesystem buffer size        */
  1664. X
  1665. X#ifndef MSDOS
  1666. Xtypedef struct
  1667. X{
  1668. X    int        dd_fd;        /* file descriptor            */
  1669. X    int        dd_loc;        /* offset in block            */
  1670. X    int        dd_size;    /* amount of valid data            */
  1671. X    char    *dd_buf;    /* -> directory block            */
  1672. X} DIR;                /* stream data from opendir()        */
  1673. X
  1674. X#else
  1675. X
  1676. X/* MSDOS versions */
  1677. X
  1678. Xstruct _dircontents {
  1679. X    char        *_d_entry;
  1680. X    struct _dircontents    *_d_next;
  1681. X};
  1682. X
  1683. Xtypedef struct _dirdesc {
  1684. X    int            dd_id;    /* uniquely identify each open directory */
  1685. X    long        dd_loc;    /* where we are in directory entry is this */
  1686. X    struct _dircontents    *dd_contents;    /* pointer to contents of dir    */
  1687. X    struct _dircontents    *dd_cp;        /* pointer to current position    */
  1688. X} DIR;
  1689. X#endif
  1690. X
  1691. X/* Functions */
  1692. X
  1693. Xextern DIR * _CDECL        opendir        _PROTO ((char *));
  1694. Xextern struct dirent * _CDECL    readdir        _PROTO ((DIR *));
  1695. Xextern void _CDECL        rewinddir    _PROTO ((DIR *));
  1696. Xextern int _CDECL        closedir    _PROTO ((DIR *));
  1697. Xextern void _CDECL        seekdir        _PROTO ((DIR *, off_t));
  1698. Xextern off_t _CDECL        telldir        _PROTO ((DIR *));
  1699. X
  1700. Xextern int _CDECL        chdir        _PROTO ((char *));
  1701. Xextern char * _CDECL        getcwd        _PROTO ((char *, int));
  1702. X#ifdef MSDOS
  1703. Xextern int _CDECL        mkdir        _PROTO ((char *));
  1704. X#else
  1705. Xextern int _CDECL        mkdir        _PROTO ((char *, mode_t));
  1706. X#endif
  1707. Xextern int _CDECL        rmdir        _PROTO ((char *));
  1708. Xextern int _CDECL        scandir        _PROTO ((char *, struct dirent ***, int (_CDECL *)(const void *, const void *), int (_CDECL *)(const void *, const void *)));
  1709. X#endif
  1710. SHAR_EOF
  1711. chmod 0644 include/dirent.h || echo "restore of include/dirent.h fails"
  1712. set `wc -c include/dirent.h`;Sum=$1
  1713. if test "$Sum" != "2014"
  1714. then echo original size 2014, current size $Sum;fi
  1715. echo "x - extracting include/unistd.h (Text)"
  1716. sed 's/^X//' << 'SHAR_EOF' > include/unistd.h &&
  1717. X#ifndef _UNISTD_H
  1718. X#define _UNISTD_H
  1719. X
  1720. X/*  unistd.h  */
  1721. X
  1722. X#include <sys/types.h>
  1723. X#include <sys/proto.h>
  1724. X
  1725. X/* Definition for NULL pointer */
  1726. X
  1727. X#ifndef NULL
  1728. X#  ifdef MSDOS
  1729. X#    if (defined(M_I86SM) || defined(M_I86MM))
  1730. X#      define NULL    0
  1731. X#    else
  1732. X#      if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
  1733. X#        define NULL    0L
  1734. X#      endif
  1735. X#    endif
  1736. X#  else
  1737. X#    define NULL    0
  1738. X#  endif
  1739. X#endif
  1740. X
  1741. X/*  for access(2)  */
  1742. X
  1743. X#define R_OK         4
  1744. X#define W_OK         2
  1745. X#define X_OK         1
  1746. X#define F_OK         0
  1747. X
  1748. X/*  for lockf()  */
  1749. X
  1750. X#define F_ULOCK        0
  1751. X#define F_LOCK        1
  1752. X#define F_TLOCK        2
  1753. X#define F_TEST        3
  1754. X
  1755. X/*  for lseek(2)  */
  1756. X
  1757. X#ifndef SEEK_SET
  1758. X#define SEEK_SET    0
  1759. X#endif
  1760. X
  1761. X#ifndef SEEK_CUR
  1762. X#define SEEK_CUR    1
  1763. X#endif
  1764. X
  1765. X#ifndef SEEK_END
  1766. X#define SEEK_END    2
  1767. X#endif
  1768. X
  1769. X/* STDIO definitions */
  1770. X
  1771. X#define    STDIN_FILENO    0
  1772. X#define    STDOUT_FILENO    1
  1773. X#define    STDERR_FILENO    2
  1774. X
  1775. X/* Standard paths */
  1776. X
  1777. X#define GF_PATH        "/etc/group"
  1778. X#define PF_PATH        "/etc/passwd"
  1779. X#define IF_PATH        "/usr/include"
  1780. X#define SF_PATH        "/etc/shadow"
  1781. X
  1782. X/* POSIX definitions */
  1783. X
  1784. X#define _POSIX_VERSION        198803L
  1785. X#undef    _POSIX_CHOWN_RESTRICTED
  1786. X#undef    _POSIX_JOB_CONTROL
  1787. X#define    _POSIX_NO_TRUNC        1
  1788. X#define _POSIX_SAVED_IDS    1
  1789. X#undef    _POSIX_VDISABLE
  1790. X/* #define _XOPEN_VERSION        */
  1791. X
  1792. X/* sysconf values */
  1793. X
  1794. X#define _SC_ARG_MAX        0
  1795. X#define _SC_CHILD_MAX        1
  1796. X#define _SC_CLK_TCK        2
  1797. X#define _SC_NGROUPS_MAX        3
  1798. X#define _SC_OPEN_MAX        4
  1799. X#define _SC_JOB_CONTROL        5
  1800. X#define _SC_SAVED_IDS        6
  1801. X#define _SC_VERSION        7
  1802. X#define _SC_PASS_MAX        8
  1803. X#define _SC_XOPEN_VERSION    9
  1804. X
  1805. X/* pathconf values */
  1806. X
  1807. X#define _PC_LINK_MAX        0
  1808. X#define _PC_MAX_CANON        1
  1809. X#define _PC_MAX_INPUT        2
  1810. X#define _PC_NAME_MAX        3
  1811. X#define _PC_PATH_MAX        4
  1812. X#define _PC_PIPE_BUF        5
  1813. X#define _PC_CHOWN_RESTRICTED    6
  1814. X#define _PC_NO_TRUNC        7
  1815. X#define _PC_VDISABLE        8
  1816. X
  1817. X/* confstring values */
  1818. X
  1819. X#define _CS_PATH        1
  1820. X
  1821. X/* Function declarations */
  1822. X
  1823. Xextern size_t _CDECL    confstring    _PROTO ((int, char *, size_t));
  1824. Xextern void _CDECL    abort        _PROTO ((void));
  1825. X#ifdef MSDOS
  1826. Xextern int _CDECL    chsize        _PROTO ((int, off_t));
  1827. X#else
  1828. Xextern int _CDECL    chsize        _PROTO ((char *, off_t));
  1829. X#endif
  1830. Xextern void _CDECL    sync        _PROTO ((void));
  1831. X
  1832. X/* --- Process creation and execution --- */
  1833. Xextern pid_t _CDECL    fork        _PROTO ((void));
  1834. Xextern pid_t _CDECL    vfork        _PROTO ((void));
  1835. Xextern int _CDECL    execl        _PROTO ((char *, char *, ...));
  1836. Xextern int _CDECL    execle        _PROTO ((char *, char *, ...));
  1837. Xextern int _CDECL    execlp        _PROTO ((char *, char *, ...));
  1838. Xextern int _CDECL    execlpe        _PROTO ((char *, char *, ...));
  1839. Xextern int _CDECL    execv        _PROTO ((char *, char **));
  1840. Xextern int _CDECL    execve        _PROTO ((char *, char **, char **));
  1841. Xextern int _CDECL    execvp        _PROTO ((char *, char **));
  1842. Xextern int _CDECL    execvpe        _PROTO ((char *, char **, char **));
  1843. X
  1844. X/* --- Process termination --- */
  1845. Xextern void _CDECL    _exit        _PROTO ((int));
  1846. Xextern void _CDECL    exit        _PROTO ((int));
  1847. X
  1848. X/* --- Timer operations --- */
  1849. Xextern unsigned int _CDECL    alarm    _PROTO ((unsigned int));
  1850. Xextern int _CDECL        pause    _PROTO ((void));
  1851. Xextern unsigned int _CDECL    sleep    _PROTO ((unsigned int));
  1852. X
  1853. X/* --- Process identification --- */
  1854. Xextern pid_t _CDECL    getpid        _PROTO ((void));
  1855. Xextern pid_t _CDECL    getppid        _PROTO ((void));
  1856. X
  1857. X/* --- User identification --- */
  1858. Xextern uid_t _CDECL    getuid        _PROTO ((void));
  1859. Xextern uid_t _CDECL    geteuid        _PROTO ((void));
  1860. Xextern gid_t _CDECL    getgid        _PROTO ((void));
  1861. Xextern gid_t _CDECL    getegid        _PROTO ((void));
  1862. Xextern int _CDECL    setuid        _PROTO ((uid_t));
  1863. Xextern int _CDECL    setgid        _PROTO ((gid_t));
  1864. Xextern int _CDECL    getgroups    _PROTO ((int, gid_t *));
  1865. Xextern char * _CDECL    getlogin    _PROTO ((void));
  1866. Xextern char * _CDECL    cuserid        _PROTO ((char *));
  1867. X
  1868. X/* --- Process groups --- */
  1869. Xextern pid_t _CDECL    getpgrp        _PROTO ((void));
  1870. Xextern pid_t _CDECL    setsid        _PROTO ((void));
  1871. Xextern int _CDECL    setpgid        _PROTO ((pid_t, pid_t));
  1872. X
  1873. X/* --- Terminal identification --- */
  1874. Xextern char * _CDECL    ctermid    _PROTO ((char *));
  1875. Xextern char * _CDECL    ttyname    _PROTO ((int));
  1876. Xextern int _CDECL    isatty        _PROTO ((int));
  1877. X
  1878. X/* --- Configurable system variables --- */
  1879. Xextern long _CDECL    sysconf        _PROTO ((int));
  1880. X
  1881. X/* --- Working directory --- */
  1882. Xextern int _CDECL    chdir        _PROTO ((char *));
  1883. Xextern char * _CDECL    getcwd        _PROTO ((char *, int));
  1884. X
  1885. X/* --- General file creation --- */
  1886. Xextern int _CDECL    link        _PROTO ((char *, char *));
  1887. Xextern int _CDECL    rename        _PROTO ((const char *, const char *));
  1888. Xextern char * _CDECL    mktemp        _PROTO ((char *));
  1889. X
  1890. X/* --- File removal --- */
  1891. Xextern int _CDECL    unlink        _PROTO ((const char *));
  1892. Xextern int _CDECL    remove        _PROTO ((const char *));
  1893. Xextern int _CDECL    rmdir        _PROTO ((char *));
  1894. X
  1895. X/* --- File characteristics --- */
  1896. Xextern int _CDECL    access        _PROTO ((char *, int));
  1897. Xextern int _CDECL    chown        _PROTO ((char *, uid_t, gid_t));
  1898. Xextern long _CDECL    tell         _PROTO ((int));
  1899. X
  1900. X/* --- Configurable pathname variables --- */
  1901. Xextern long _CDECL    pathconf    _PROTO ((char *, int));
  1902. Xextern long _CDECL    fpathconf    _PROTO ((int, int));
  1903. X
  1904. X/* --- Pipes --- */
  1905. Xextern int _CDECL    pipe        _PROTO ((int[2]));
  1906. X
  1907. X/* --- File descriptor manipulation --- */
  1908. Xextern int _CDECL    dup        _PROTO ((int));
  1909. Xextern int _CDECL    dup2        _PROTO ((int, int));
  1910. X
  1911. X/* --- File descriptor deassignment --- */
  1912. Xextern int _CDECL    close        _PROTO ((int));
  1913. X
  1914. X/* --- Input and output --- */
  1915. Xextern int _CDECL    read        _PROTO ((int, char *, unsigned int));
  1916. Xextern int _CDECL    write        _PROTO ((int, char *, unsigned int));
  1917. X
  1918. X/* --- Control operations on files --- */
  1919. Xextern off_t _CDECL    lseek        _PROTO ((int, off_t, int));
  1920. X#endif
  1921. SHAR_EOF
  1922. chmod 0644 include/unistd.h || echo "restore of include/unistd.h fails"
  1923. set `wc -c include/unistd.h`;Sum=$1
  1924. if test "$Sum" != "5401"
  1925. then echo original size 5401, current size $Sum;fi
  1926. echo "x - extracting include/ms_dio.h (Text)"
  1927. sed 's/^X//' << 'SHAR_EOF' > include/ms_dio.h &&
  1928. X/* ms_dio.h */
  1929. X#ifndef _MS_DIO_H
  1930. X#define _MS_DIO_H
  1931. X
  1932. X/*
  1933. X * This is only required under MSDOS
  1934. X */
  1935. X
  1936. X#ifdef MSDOS
  1937. X#include <sys/proto.h>
  1938. X
  1939. Xextern int _CDECL    dio_write    _PROTO ((int, char *, unsigned int));
  1940. Xextern int _CDECL    dio_read    _PROTO ((int, char *, unsigned int));
  1941. Xextern int _CDECL    dio_open    _PROTO ((char *, int, ...));
  1942. Xextern int _CDECL    dio_close    _PROTO ((int));
  1943. Xextern long _CDECL    dio_lseek    _PROTO ((int, long, int));
  1944. Xextern int _CDECL    dio_fstat    _PROTO ((int , struct stat *));
  1945. Xextern int _CDECL    dio_stat    _PROTO ((char *, struct stat *));
  1946. Xextern int _CDECL    dio_access    _PROTO ((char *, int));
  1947. Xextern int _CDECL    dio_chmod    _PROTO ((char *, int));
  1948. Xextern int _CDECL    dio_creat    _PROTO ((char *, int));
  1949. Xextern int _CDECL    dio_dup        _PROTO ((int));
  1950. Xextern int _CDECL    dio_isatty    _PROTO ((int));
  1951. Xextern long _CDECL    dio_tell    _PROTO ((int));
  1952. X
  1953. X#define open        dio_open
  1954. X#define close(a)    dio_close (a)
  1955. X#define read(a,b,c)    dio_read (a,b,c)
  1956. X#define write(a,b,c)    dio_write (a,b,c)
  1957. X#define lseek(a,b,c)    dio_lseek (a,b,c)
  1958. X#define fstat(a,b)    dio_fstat (a,b)
  1959. X#define stat(a,b)    dio_stat (a,b)
  1960. X#define access(a, b)    dio_access (a,b)
  1961. X#define chmod(a, b)    dio_chmod (a,b)
  1962. X#define creat(a, b)    dio_creat (a,b)
  1963. X#define dup(a)        dio_dup (a)
  1964. X#define isatty(a)    dio_isatty (a)
  1965. X#define tell(a)        dio_tell (a)
  1966. X#endif
  1967. X#endif
  1968. SHAR_EOF
  1969. chmod 0644 include/ms_dio.h || echo "restore of include/ms_dio.h fails"
  1970. set `wc -c include/ms_dio.h`;Sum=$1
  1971. if test "$Sum" != "1284"
  1972. then echo original size 1284, current size $Sum;fi
  1973. echo "x - extracting lib/ms_dio.c (Text)"
  1974. sed 's/^X//' << 'SHAR_EOF' > lib/ms_dio.c &&
  1975. X/* MS-DOS Direct Disk I/O
  1976. X *
  1977. X * MS-DOS Direct Disk I/O - Copyright (c) 1989 Data Logic Limited.
  1978. X *
  1979. X * dio_read and dio_write based on original code copyrighted (c) 1989
  1980. X * Harold G. Walters.
  1981. X *
  1982. X * The rest of the code has been written from scatch to support multiple disk
  1983. X * access and provide a consistant interface from normal I/O operations.
  1984. X *
  1985. X * The devices supported are:
  1986. X *
  1987. X *    /dev/hdxy    - Hard disk drive x parition y (x = 0 to 9, y =
  1988. X *              0 to 9, where 0 is the whole disk).
  1989. X *    /dev/fdx    - Floppy drive x (x = 0 to 9).
  1990. X *    /dev/kmem    - Memory driver
  1991. X *
  1992. X * It does its best to determine what type of disk you are reading.
  1993. X *
  1994. X * Redistribution and use in source and binary forms are permitted
  1995. X * provided that the above copyright notice is duplicated in the
  1996. X * source form.
  1997. X */
  1998. X
  1999. X#include <sys/types.h>
  2000. X#include <sys/stat.h>
  2001. X#include <stdio.h>
  2002. X#include <stdlib.h>
  2003. X#include <string.h>
  2004. X#include <errno.h>
  2005. X#include <dos.h>
  2006. X#include <fcntl.h>
  2007. X#include <ctype.h>
  2008. X#include <unistd.h>
  2009. X#include <time.h>
  2010. X#include <ms_dio.h>
  2011. X
  2012. X#undef open
  2013. X#undef close
  2014. X#undef read
  2015. X#undef write
  2016. X#undef lseek
  2017. X#undef fstat
  2018. X#undef stat
  2019. X#undef access
  2020. X#undef chmod
  2021. X#undef creat
  2022. X#undef dup
  2023. X#undef isatty
  2024. X#undef tell
  2025. X
  2026. X#define SECSIZ        512
  2027. X#define    MS_MODIFIER    30000
  2028. X#define BIOS_READ    0x2
  2029. X#define BIOS_WRITE    0x3
  2030. X#define HD_FLAG        0x80        /* Hard disk flag        */
  2031. X#define MEGABYTE    1048576L
  2032. X#define DRIVE_RAM    20
  2033. X
  2034. X#ifdef __STDC__
  2035. Xstatic int        dio_do (int, struct fs *, char *, long, unsigned int);
  2036. Xstatic struct fs    *dio_fpcheck (int);
  2037. Xstatic int        dio_fncheck (char *);
  2038. X#else
  2039. Xstatic int        dio_do ();
  2040. Xstatic struct fs    *dio_fpcheck ();
  2041. Xstatic int        dio_fncheck ();
  2042. X#endif
  2043. X
  2044. Xstatic struct fs {
  2045. X    int        mode;            /* Open mode            */
  2046. X    int        drive;
  2047. X    int        partition;        /* Hard disk partition number    */
  2048. X    off_t    location;        /* Current offset        */
  2049. X    long    m_start;        /* Offset for partition        */
  2050. X    long    m_cyl;            /* Max cylinders        */
  2051. X    int        m_head;            /* Max heads            */
  2052. X    int        m_sector;        /* Max sectors            */
  2053. X    long    m_scount;        /* Total sectors per disk    */
  2054. X} *MS_io_fs[_NFILE];
  2055. X
  2056. Xstruct partition {
  2057. X    long    f_type;            /* Type flags            */
  2058. X    long    f_status;        /* Status flags            */
  2059. X    long    offset;            /* Offset in sectors        */
  2060. X    long    size;            /* Size in sectors        */
  2061. X};
  2062. X
  2063. Xstatic int    fs_init = 0;
  2064. X
  2065. X/* Do the actual read/write to the disk.  This function is not used
  2066. X * for the RAM drive
  2067. X */
  2068. X
  2069. Xstatic int    dio_do (type, FP, buf, secnum, secknt)
  2070. Xint        type;
  2071. Xstruct fs    *FP;
  2072. Xchar        *buf;
  2073. Xlong        secnum;
  2074. Xunsigned int    secknt;
  2075. X{
  2076. X    int            i, j;
  2077. X    int            nsec, cyl;
  2078. X    long        asec;
  2079. X    union REGS        reg;
  2080. X#if defined(M_I86LM)
  2081. X    struct SREGS    sreg;
  2082. X#endif
  2083. X
  2084. X    for (j = 0; j < secknt; j += nsec, buf += (nsec * SECSIZ), secnum += nsec)
  2085. X    {
  2086. X
  2087. X/* Check for space - end of drive */
  2088. X
  2089. X    if (secnum > FP->m_scount)
  2090. X    {
  2091. X        errno = ENOSPC;
  2092. X        return j * SECSIZ;
  2093. X    }
  2094. X
  2095. X/* Calculate the number of sectors left on the track */
  2096. X
  2097. X    asec = FP->m_start + secnum;
  2098. X
  2099. X    if (((asec % FP->m_sector) + (secknt - j)) > FP->m_sector)
  2100. X        nsec = (int)(FP->m_sector - (asec % FP->m_sector));
  2101. X
  2102. X    else
  2103. X        nsec = secknt - j;
  2104. X
  2105. X/* Read/write it three times */
  2106. X
  2107. X    for (i = 0; i < 3; i++)
  2108. X    {
  2109. X        reg.h.ah = (unsigned char)type;
  2110. X        reg.h.al = (unsigned char)nsec;
  2111. X        reg.h.dl = (unsigned char)FP->drive;
  2112. X
  2113. X        cyl      = (int)(asec / (FP->m_head * FP->m_sector));
  2114. X        reg.h.cl = (unsigned char)((((asec % FP->m_sector) + 1) & 0x03f) |
  2115. X            ((cyl & 0x0300) >> 2));
  2116. X        reg.h.ch = (unsigned char)(cyl & 0xff);
  2117. X        reg.h.dh = (unsigned char)((asec % (FP->m_head * FP->m_sector)) / FP->m_sector);
  2118. X
  2119. X
  2120. X#if defined(M_I86LM)
  2121. X        reg.x.bx = FP_OFF(buf);
  2122. X        sreg.es = FP_SEG(buf);
  2123. X        int86x (0x13, ®, ®, &sreg);
  2124. X#else
  2125. X        reg.x.bx = (int) buf;
  2126. X        int86 (0x13, ®, ®);
  2127. X#endif
  2128. X
  2129. X        if (!reg.x.cflag)
  2130. X        break;
  2131. X    }
  2132. X
  2133. X/* Check for failure */
  2134. X
  2135. X    if (i == 3)
  2136. X    {
  2137. X        errno = EIO;
  2138. X        return -1;
  2139. X    }
  2140. X    }
  2141. X
  2142. X    return secknt * SECSIZ;
  2143. X}
  2144. X
  2145. X/* Write function */
  2146. X
  2147. Xint        dio_write (fp, from_buf, from_cnt)
  2148. Xint        fp;            /* File handler            */
  2149. Xchar        *from_buf;        /* Output buffer        */
  2150. Xunsigned int    from_cnt;        /* Number of bytes to write    */
  2151. X{
  2152. X    unsigned int    amt = 0;
  2153. X    unsigned int    err = 0;
  2154. X    long        fquo;
  2155. X    unsigned int    frem;
  2156. X    unsigned int    cquo = 0;
  2157. X    unsigned int    crem = 0;
  2158. X    struct fs        *FP;
  2159. X    char        buffer[SECSIZ];
  2160. X
  2161. X/* Direct IO or normal */
  2162. X
  2163. X    if (fp < MS_MODIFIER)
  2164. X    return write (fp, from_buf, from_cnt);
  2165. X
  2166. X    if (((FP = dio_fpcheck (fp)) == (struct fs *)NULL) ||
  2167. X    ((FP->mode & 0x03) == O_RDONLY))
  2168. X    {
  2169. X    errno = EBADF;
  2170. X    return -1;
  2171. X    }
  2172. X
  2173. X/* If RAM - just copy */
  2174. X
  2175. X    if (FP->drive == DRIVE_RAM)
  2176. X    {
  2177. X    char huge     *cp = (char huge *)from_buf;
  2178. X    char huge     *sp = (char huge *)(((FP->location & 0x0ffff0L) << 12L)
  2179. X                        | (FP->location & 0x0fL));
  2180. X
  2181. X    amt = from_cnt;
  2182. X    while (amt--)
  2183. X        *(sp++) = *(cp++);
  2184. X
  2185. X    return from_cnt;
  2186. X    }
  2187. X
  2188. X/* If the current location is not a sector boundary - read in the current
  2189. X * sector and write a bit at the end to move to the boundary
  2190. X */
  2191. X
  2192. X    fquo = FP->location / SECSIZ;
  2193. X    frem = (unsigned int) (FP->location % SECSIZ);
  2194. X
  2195. X    if (frem > 0)
  2196. X    {
  2197. X    if ((err = dio_do (BIOS_READ, FP, buffer, fquo, 1)) != SECSIZ)
  2198. X        return err;
  2199. X
  2200. X    if ((amt = SECSIZ - frem) > from_cnt)
  2201. X        amt = from_cnt;
  2202. X
  2203. X/* Update the buffer with the bit at the end */
  2204. X
  2205. X    memcpy (&buffer[frem], from_buf, amt);
  2206. X
  2207. X    if ((err = dio_do (BIOS_WRITE, FP, buffer, fquo, 1)) != SECSIZ)
  2208. X        return err;
  2209. X
  2210. X/* Increment the location */
  2211. X
  2212. X    FP->location += amt;
  2213. X
  2214. X    if (SECSIZ - frem <= from_cnt)
  2215. X        fquo++;
  2216. X
  2217. X    from_buf += amt;
  2218. X    from_cnt -= amt;
  2219. X    }
  2220. X
  2221. X/* Calculate the number of full sectors to process now we are on a sector
  2222. X * boundary
  2223. X */
  2224. X
  2225. X    cquo = from_cnt / SECSIZ;
  2226. X    crem = from_cnt % SECSIZ;
  2227. X
  2228. X    if (cquo > 0)
  2229. X    {
  2230. X    if ((err = dio_do (BIOS_WRITE, FP, from_buf, fquo, cquo)) !=
  2231. X        (cquo * SECSIZ))
  2232. X    {
  2233. X        if (err > 0)
  2234. X        FP->location += err;
  2235. X
  2236. X        return err;
  2237. X    }
  2238. X
  2239. X    amt += (cquo * SECSIZ);
  2240. X    FP->location += (cquo * SECSIZ);
  2241. X    fquo += cquo;
  2242. X    from_buf += (cquo * SECSIZ);
  2243. X    from_cnt -= (cquo * SECSIZ);
  2244. X    }
  2245. X
  2246. X/* Is there still more - read in the next sector, update first half and
  2247. X * re-write
  2248. X */
  2249. X
  2250. X    if (crem > 0)
  2251. X    {
  2252. X    if ((err = dio_do (BIOS_READ, FP, buffer, fquo, 1)) != SECSIZ)
  2253. X        return err;
  2254. X
  2255. X    memcpy (buffer, from_buf, crem);
  2256. X
  2257. X    if ((err = dio_do (BIOS_WRITE, FP, buffer, fquo, 1)) != SECSIZ)
  2258. X        return err;
  2259. X
  2260. X    amt += crem;
  2261. X    FP->location += crem;
  2262. X    }
  2263. X
  2264. X    return amt;
  2265. X}
  2266. X
  2267. X/* Read function */
  2268. X
  2269. Xint        dio_read (fp, to_buf, to_cnt)
  2270. Xint        fp;            /* File handler            */
  2271. Xchar        *to_buf;        /* Input buffer            */
  2272. Xunsigned int    to_cnt;            /* Number of bytes to read    */
  2273. X{
  2274. X    unsigned int    amt = 0;
  2275. X    unsigned int    err = 0;
  2276. X    long        fquo;
  2277. X    unsigned int    frem;
  2278. X    unsigned int    cquo = 0;
  2279. X    unsigned int    crem = 0;
  2280. X    struct fs        *FP;
  2281. X    char        buffer[SECSIZ];
  2282. X
  2283. X/* Direct IO or normal */
  2284. X
  2285. X    if (fp < MS_MODIFIER)
  2286. X    return read (fp, to_buf, to_cnt);
  2287. X
  2288. X    if (((FP = dio_fpcheck (fp)) == (struct fs *)NULL) ||
  2289. X    ((FP->mode & 0x03) == O_WRONLY))
  2290. X    {
  2291. X    errno = EBADF;
  2292. X    return -1;
  2293. X    }
  2294. X
  2295. X/* If RAM - just copy */
  2296. X
  2297. X    if (FP->drive == DRIVE_RAM)
  2298. X    {
  2299. X    char huge     *cp = (char huge *)to_buf;
  2300. X    char huge     *sp = (char huge *)(((FP->location & 0x0ffff0L) << 12L)
  2301. X                        | (FP->location & 0x0f));
  2302. X
  2303. X
  2304. X    amt = to_cnt;
  2305. X    while (amt--)
  2306. X        *(cp++) = *(sp++);
  2307. X
  2308. X    return to_cnt;
  2309. X    }
  2310. X
  2311. X    fquo = FP->location / SECSIZ;
  2312. X    frem = (unsigned int) (FP->location % SECSIZ);
  2313. X
  2314. X    if (frem > 0)
  2315. X    {
  2316. X    if ((err = dio_do (BIOS_READ, FP, buffer, fquo, 1)) != SECSIZ)
  2317. X        return err;
  2318. X
  2319. X    if ((amt = SECSIZ - frem) > to_cnt)
  2320. X        amt = to_cnt;
  2321. X
  2322. X    memcpy (to_buf, &buffer[frem], amt);
  2323. X
  2324. X    FP->location += amt;
  2325. X    if (SECSIZ - frem <= to_cnt)
  2326. X        fquo++;
  2327. X
  2328. X    to_buf += amt;
  2329. X    to_cnt -= amt;
  2330. X    }
  2331. X
  2332. X    cquo = to_cnt / SECSIZ;
  2333. X    crem = to_cnt % SECSIZ;
  2334. X
  2335. X    if (cquo > 0)
  2336. X    {
  2337. X    if ((err = dio_do (BIOS_READ, FP, to_buf, fquo, cquo)) !=
  2338. X        (cquo * SECSIZ))
  2339. X    {
  2340. X        if (err > 0)
  2341. X        FP->location += err;
  2342. X
  2343. X        return err;
  2344. X    }
  2345. X
  2346. X    amt += (cquo * SECSIZ);
  2347. X    FP->location += (cquo * SECSIZ);
  2348. X    fquo += cquo;
  2349. X    to_buf += (cquo * SECSIZ);
  2350. X    to_cnt -= (cquo * SECSIZ);
  2351. X    }
  2352. X
  2353. X/* Do we still need a partial sector ? */
  2354. X
  2355. X    if (crem > 0)
  2356. X    {
  2357. X    if ((err = dio_do (BIOS_READ, FP, buffer, fquo, 1)) != SECSIZ)
  2358. X        return err;
  2359. X
  2360. X    memcpy (to_buf, buffer, crem);
  2361. X    amt += crem;
  2362. X    FP->location += crem;
  2363. X    }
  2364. X
  2365. X    return (amt);
  2366. X}
  2367. X
  2368. Xint    dio_open (name, mode, permissions)
  2369. Xchar    *name;
  2370. Xint    mode;
  2371. Xmode_t    permissions;
  2372. X{
  2373. X    struct fs    *FP;
  2374. X    int        fp, i, j;
  2375. X    int        drive, ndrive;
  2376. X    union REGS    iregs;
  2377. X    char    buf[SECSIZ];
  2378. X
  2379. X/* Check for initialisation */
  2380. X
  2381. X    if (!(fs_init++))
  2382. X    memset (MS_io_fs, 0, sizeof (struct fs *) * _NFILE);
  2383. X
  2384. X/* Direct I/o file name */
  2385. X
  2386. X    if ((drive = dio_fncheck (name)) != -1)
  2387. X    {
  2388. X    for (fp = 0; (fp < _NFILE) && (MS_io_fs[fp] != (struct fs *)NULL); fp++)
  2389. X        ;
  2390. X
  2391. X/* Check for available entry and space */
  2392. X
  2393. X    if ((fp == _NFILE) ||
  2394. X        ((FP = (struct fs *)malloc (sizeof (struct fs))) == (struct fs *)NULL))
  2395. X    {
  2396. X        errno = ENFILE;
  2397. X        return -1;
  2398. X    }
  2399. X
  2400. X    FP->location = 0L;
  2401. X    FP->mode = mode;
  2402. X
  2403. X/* RAM access ? */
  2404. X
  2405. X    if (drive == DRIVE_RAM)
  2406. X    {
  2407. X        FP->drive    = drive;
  2408. X        MS_io_fs[fp] = FP;
  2409. X        return fp + MS_MODIFIER;
  2410. X    }
  2411. X
  2412. X    if (drive & HD_FLAG)
  2413. X    {
  2414. X        ndrive      = (drive & (~HD_FLAG));
  2415. X        FP->partition = ndrive % 10;
  2416. X        ndrive      /= 10;
  2417. X        FP->drive     = ndrive | HD_FLAG;
  2418. X        FP->m_start   = 0L;        /* Offset for partition        */
  2419. X    }
  2420. X
  2421. X    else
  2422. X    {
  2423. X        FP->drive     = drive;
  2424. X        ndrive        = drive;
  2425. X        FP->partition = 0;
  2426. X        FP->m_start   = 0L;        /* Offset for partition        */
  2427. X    }
  2428. X
  2429. X
  2430. X/* Reset the drive */
  2431. X
  2432. X    iregs.h.ah = 0;
  2433. X    iregs.h.dl = (unsigned char)FP->drive;
  2434. X    int86 (0x13, &iregs, &iregs);
  2435. X
  2436. X/* Get the drive parameters */
  2437. X
  2438. X    iregs.h.ah = 0x08;
  2439. X    iregs.h.dl = (unsigned char)FP->drive;
  2440. X    int86 (0x13, &iregs, &iregs);
  2441. X
  2442. X/* Check for hard disk */
  2443. SHAR_EOF
  2444. echo "End of part 1"
  2445. echo "File lib/ms_dio.c is continued in part 2"
  2446. echo "2" > s2_seq_.tmp
  2447. exit 0
  2448.  
  2449. -- 
  2450. Regards,
  2451.  
  2452. Ian Stewartson
  2453. Data Logic Ltd.
  2454.  
  2455.